Body Animation Isn't Smooth
The 'spaceShip' in the following code isn't moving smoothly at the beginning of holding any arrow key down. It moves one step, freezes for a split second, and then moves 'smoothly'
Solution 1:
The problem is that you wait for each keydown
event to update the ship position.
The keydown event has a delay before it triggers again : the delay you are experiencing at beginning and the jump you face at each redraw.
The solution here is to trigger the movement on keydown
and release it on keyup
. This way, your ship will move smoothly as soon as you push the button.
// Im' assuming most of visitors here have recent browsers, so I removed the rAF polyfill for readibility// If you wrap it after the canvas element decalaration, you can already populate this variable, it will avoid that you make a lot of calls to document.getElementById()var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// ship datavar shipPositionX = canvas.width / 2;
// Just for the snippet heightvar shipPositionY = 0;
var deltaShipPositionX = 10;
var deltaShipPositionY = 10;
//Removed the init() function, since our elements are loaded.functiondraw() {
clear();
createRectangleToCoverCanvas();
createSpaceShip(shipPositionX, shipPositionY, 10);
}
functionclear() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
functioncreateRectangleToCoverCanvas() {
ctx.fillStyle = 'black';
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.stroke();
}
functioncreateSpaceShip(x, y, radius) {
ctx.fillStyle = 'white'
ctx.strokeStyle = 'white'
ctx.beginPath();
ctx.rect(x, y, 20, 20);
ctx.fill();
ctx.stroke();
}
// instantiate a variable that will store our animationFrame id, so we can cancel it furthervar raf,
// the direction object, with an x and y values
direction = {
x: 0,
y: 0
};
// we can set a speed variablevar speed = 2.5;
functiontriggerMoveSpaceShip(event) {
switch (event.keyCode) {
// leftcase37:
// update the direction object
direction.x = -speed;
// avoid the scroll in the snippet
event.preventDefault();
break;
// upcase38:
direction.y = -speed;
event.preventDefault();
break;
// rightcase39:
direction.x = speed;
event.preventDefault();
break;
//downcase40:
direction.y = speed;
event.preventDefault();
break;
}
// if we haven't initiated the animation yet, and that our direction is not 0, then do it nowif (!raf && (direction.x || direction.y)) moveSpaceShip();
}
functionreleaseMoveSpaceShip(event) {;
switch (event.keyCode) {
// leftcase37:
//reset this direction
direction.x = 0;
break;
// upcase38:
direction.y = 0;
break;
// rightcase39:
direction.x = 0;
break;
//downcase40:
direction.y = 0;
break;
}
if (!direction.x && !direction.y) {
// if none of the directions is set, stop the animationcancelAnimationFrame(raf);
raf = undefined;
}
}
functionmoveSpaceShip() {
// declare our animation functionvar move = function() {
// update the positions without going out of the screen// Sorry, this is dirty...if(direction.x){
if(
(shipPositionX > 0 && shipPositionX < canvas.width-20) ||
(shipPositionX <= 0 && direction.x > 0) ||
(shipPositionX >= canvas.width-20 && direction.x < 0))
shipPositionX += direction.x;
}
if(direction.y){
if(
(shipPositionY > 0 && shipPositionY < canvas.height-20) ||
(shipPositionY <= 0 && direction.y > 0) ||
(shipPositionY >= canvas.width-20 && direction.y < 0))
shipPositionY += direction.y;
}
// finally draw ou shipdraw();
// update our raf id
raf = requestAnimationFrame(move);
};
// let's go !
raf = requestAnimationFrame(move);
}
draw();
window.addEventListener('keydown', triggerMoveSpaceShip, true);
window.addEventListener('keyup', releaseMoveSpaceShip, true);
canvas {
margin: auto;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 1px solid black;
}
body{
overflow: none;
}
<canvasid="canvas"width="400"height="200"></canvas>
Post a Comment for "Body Animation Isn't Smooth"