Reputation: 2799
I created a cloud shape in canvas, and I'm wondering how I can scale the shape back and forth between larger and smaller. Like I want the cloud to get bigger, than smaller, then bigger then smaller, etc.
I was able to be able to move a separate canvas image up and down using a when-then method, but I don't think that method will work by increasing the canvas size because the actual image stays to scale.
Here is my canvas code:
<script>
var canvas = document.getElementById('hardware-cloud');
var context = canvas.getContext('2d');
// begin cloud shape-Hardware
context.beginPath();
context.moveTo(180, 80);
context.bezierCurveTo(150, 132, 143, 165, 203, 154);
context.bezierCurveTo(203, 154, 180, 200, 260, 175);
context.bezierCurveTo(297, 231, 352, 198, 344, 185);
context.bezierCurveTo(344, 185, 372, 215, 374, 175);
context.bezierCurveTo(473, 165, 462, 132, 429, 110);
context.bezierCurveTo(473, 44, 407, 33, 374, 55);
context.bezierCurveTo(352, 10, 275, 22, 275, 55);
context.bezierCurveTo(210, 20, 165, 22, 180, 80);
// complete cloud shape-Hardware
context.closePath();
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
//font inside hardware cloud
context.beginPath();
context.font = 'bold 15pt Calibri';
context.textAlign = 'center';
context.fillStyle ="navy"; // <-- Text colour here
context.fillText('Why not the electronic store?', 300, 120);
context.lineWidth = 2;
context.strokeStyle = 'grey';
context.stroke();
context.closePath();
//top hardware circle
context.beginPath();
context.arc(380, 220, 13, 0, Math.PI * 2, false);
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
context.closePath();
//middle hardware circle
context.beginPath();
context.arc(398, 253, 10, 0, Math.PI * 2, false);
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
context.closePath();
//bottom hardware circle
context.beginPath();
context.arc(425, 273, 7, 0, Math.PI * 2, false);
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
context.closePath();
</script>
And here is my attempt at the jQuery. The first part of it is to get the div region to slide into view. The second part is an attempt to scale up and down.:
$(document).ready(function(){
$('#hardware').hide();
$('#hardware').show("slide", {direction: "left"}, 400 );
ani();
function ani(){
$.when(
$('#hardware-cloud').effect({
scale: "120"},700),
$('#hardware-cloud').effect({
scale: "100"},700)
.then(ani));}
});
Upvotes: 0
Views: 1256
Reputation:
You can use scale and translate to change the size of the shape.
All transforms works for the next drawn shape and doesn't affect already drawn shapes.
So for it to work you'll need to clear the canvas, transform and then redraw the shape.
For example, re-factor the code so that you can call shape()
to draw the cloud, then:
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.scale(scaleX, scaleY);
ctx.translate(deltaX, deltaY);
shape();
requestAnimationFrame()
in a loop.Scale value is 1 = 1:1, 0.5 = half etc. Just remember these transforms are accumulative (you can use setTransform()
to set absolute transforms each time).
Update
Here is one way you can do this:
var maxScale = 1, // for demo, this represents "max"
current = 0, // angle (in radians) used to scale smoother
step = 0.02, // speed
pi2 = Math.PI; // cached value
// main loop clears, transforms and redraws shape
function loop() {
context.clearRect(0, 0, canvas.width, canvas.height);
transform();
drawShape();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
// set scale based on rotation
function transform() {
current += step;
current %= pi2;
// just play around with different combinations here
var s = (maxScale * Math.abs(Math.sin(current))) / maxScale + 0.5;
// set absolute scale
context.setTransform(s, 0, 0, s, 0, 0);
}
// wrap shape calls in a function so it can be reused
function drawShape() {
// begin cloud shape-Hardware
context.beginPath();
... rest goes here...
In addition you can use translate()
to re-position the shape linked to the rotation value.
Hope this helps!
Upvotes: 2