Reputation: 2712
i have a bunch of points that i wanted to slowly draw. I try setTimeOut and the effect from this tutorial. But without so much success.
The Function looks like this
Function:
var myFunction = function(ctx, grid, points) {
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
ctx.lineWidth = 2;
ctx.strokeStyle = '#2068A8';
ctx.fillStyle = '#2068A8';
var count = 1;
for (count = 1; count < points.length; count++) {
ctx.lineTo(points[count].x , points[count].y);
}
ctx.stroke();
}
Around this function there a many other drawing functions but i just want to animate only one.
How can i slowly draw a function with canvas?
Upvotes: 5
Views: 10392
Reputation: 1
Thanks for these examples, Loktar! This is supposed to be a comment on the second example above in the answer posted by Loktar, but I can't do a comment because I just signed up and I don't have enough "reputation".
I tried the 2nd Demo above, and if you slow down the speed, you'll notice that the new line segments start growing from the point BEFORE the point that it's supposed to be starting from. This is how I tweaked it to make it work:
I changed the following line:
ctx.lineTo(points[p].x, points[p].y);
// =>
ctx.lineTo(points[p+1].x, points[p+1].y);
and now the result looks very smooth. I'm commenting because Loktar's post was almost perfect, and I hope people don't miss out on his post just because of one little detail that needed to be tweaked. Thanks again, Loktar!
Upvotes: 0
Reputation: 35309
There's two ways you can go about doing this that I can think of off the top of my head. One is basically drawing a point and pausing for a certain amount of time before drawing the other point. That's the first example I provided.The second method involves drawing partial lines to the current target, which gives a much smoother drawing appearance. As a side note I use requestAnimationFrame
in both examples, its the recommended way to do any types of canvas animations.
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 200;
var points = [],
currentPoint = 1,
nextTime = new Date().getTime()+500,
pace = 200;
// make some points
for (var i = 0; i < 50; i++) {
points.push({
x: i * (canvas.width/50),
y: 100+Math.sin(i) * 10
});
}
function draw() {
if(new Date().getTime() > nextTime){
nextTime = new Date().getTime() + pace;
currentPoint++;
if(currentPoint > points.length){
currentPoint = 0;
}
}
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
ctx.lineWidth = 2;
ctx.strokeStyle = '#2068A8';
ctx.fillStyle = '#2068A8';
for (var p = 1, plen = currentPoint; p < plen; p++) {
ctx.lineTo(points[p].x, points[p].y);
}
ctx.stroke();
requestAnimFrame(draw);
}
draw();
If you notice that is a bit choppy, you can do the following to get smoother lines being drawn
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 200;
var points = [],
currentPoint = 1,
speed = 2,
targetX = 0,
targetY = 0,
x = 0,
y = 0;
// make some points
for (var i = 0; i < 50; i++) {
points.push({
x: i * (canvas.width/50),
y: 100+Math.sin(i) * 10
});
}
// set the initial target and starting point
targetX = points[1].x;
targetY = points[1].y;
x = points[0].x;
y = points[0].y;
function draw() {
var tx = targetX - x,
ty = targetY - y,
dist = Math.sqrt(tx*tx+ty*ty),
velX = (tx/dist)*speed,
velY = (ty/dist)*speed;
x += velX
y += velY;
if(dist < 1){
currentPoint++;
if(currentPoint >= points.length){
currentPoint = 1;
x = points[0].x;
y = points[0].y;
}
targetX = points[currentPoint].x;
targetY = points[currentPoint].y;
}
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
ctx.lineWidth = 2;
ctx.strokeStyle = '#2068A8';
ctx.fillStyle = '#2068A8';
for (var p = 0, plen = currentPoint-1; p < plen; p++) {
ctx.lineTo(points[p].x, points[p].y);
}
ctx.lineTo(x, y);
ctx.stroke();
requestAnimFrame(draw);
}
draw();
Upvotes: 10