Reputation: 415
I am trying to create what I thought would be a simple Canvas to move a point from A to B using requestAnimationFrame
.
http://jsfiddle.net/p1L81yk4/1/
Unfortunately it is not showing anything, and the animation loop seems to be headed towards infinity.
Can anyone explain what I am doing wrong? And is there a flag I can create to show when the animation should stop?
var startX = 10,
startY = 10;
var endX = 200,
endY = 350;
var speed = 1;
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var moves = distance / speed;
var xunits = (dx / moves);
var yunits = (dy / moves);
var posit = {
x: startX,
y: startY
};
var fps = 60;
var delay = 1000 / 30;
function draw() {
ctx.clearRect(0, 0, canv.width, canv.height);
ctx.save();
ctx.translate(startX, startY);
ctx.beginPath();
ctx.arc(0, 0, 5, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
function move() {
startX += dx;
startY += dy;
console.log(posit);
if (moves > 0) {
moves++;
posit.x += xunits;
posit.y += yunits;
}
}
var start = 0;
function animate() {
running = true;
var current = new Date().getTime(),
delta = current - start;
if (delta >= delay) {
move();
draw();
start = new Date().getTime();
}
anim = requestAnimationFrame(animate);
}
animate();
Upvotes: 0
Views: 295
Reputation: 17330
Using basic trigonometry you can make the entire code look and read easier, with less up front variables. I still need to set quite a lot of variables here, but you would want to mostly calculate them on the fly (which means you would have to move things like angle, from and to value and distance into the myDraw()
function).
var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');
myContext.fillStyle = '#000';
// Values expressed as x, y, positions
var fromValue = [300,20];
var toValue = [100,100];
// time expressed in Milliseconds
var time = 5000;
var start = Date.now();
// Get the angle with the arctangent function
// tan(angle) = opposite / adjacent => atan(opposite / adjacent) = angle
// atan2 is used because you can pass it the lengths and it takes care of
// some negative edge cases.
var angle = Math.atan2(toValue[0] - fromValue[0], toValue[1] - fromValue[1]);
// Basic distance because.. Pythagoras. (a^2 = sqrt(b^2 + c^2))
var distance = Math.sqrt(Math.pow(toValue[0] - fromValue[0], 2) + Math.pow(toValue[1] - fromValue[1], 2));
function myDraw(now){
// The max distance can be divided by the total time, multiplied by the time that has passed
var t = (distance / time * (now - start));
var x = fromValue[0] + Math.sin(angle) * t;
var y = fromValue[1] + Math.cos(angle) * t;
// Clear the canvas by resetting its width
myCanvas.width = myCanvas.width;
// Draw the arc at position x and y
myContext.arc(x, y, 3, 0, Math.PI * 2);
myContext.fill();
// Return false if the animation is done.
if(now < start + time) return true;
else return false;
}
function myAnimate(){
// Keep executing as long as myDraw() returns true
if(myDraw(Date.now())) window.requestAnimationFrame(myAnimate);
}
myAnimate();
<canvas width="500" height="500" id="myCanvas" />
Upvotes: 1
Reputation: 2012
save
and restore
, these functions is for saving and restoring the images.posit.x
and posit.y
instead of startX
and startY
.startX
and startY
which is not reasonable.if
to determinate if or if not to continue aniamtion.Which ends up with a working code:
var canv = document.getElementById('canv'),
ctx = canv.getContext('2d');
var startX = 10,
startY = 10;
var endX = 200,
endY = 350;
var speed = 2;
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var moves = distance / speed;
var xunits = (dx / moves);
var yunits = (dy / moves);
var posit = {
x: startX,
y: startY
};
var fps = 60;
var delay = 1000 / 60;
function draw() {
ctx.clearRect(0, 0, canv.width, canv.height);
//ctx.save();
ctx.translate(posit.x, posit.y);
ctx.beginPath();
ctx.arc(0, 0, 5, 0, Math.PI * 2);
ctx.fill();
ctx.translate(-posit.x, -posit.y);
//ctx.restore();
}
function move() {
//startX += dx;
//startY += dy;
//console.log(posit);
if (moves > 0) {
moves++;
posit.x += xunits;
posit.y += yunits;
}
}
var start = 0;
function animate() {
running = true;
var current = new Date().getTime(),
delta = current - start;
if (delta >= delay) {
move();
draw();
start = new Date().getTime();
}
if(posit.y < endY)
anim = requestAnimationFrame(animate);
}
animate();
<canvas id="canv" width="500" height="500"></canvas>
Upvotes: 2