Skip to content Skip to sidebar Skip to footer

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>

uncommented fiddle

Post a Comment for "Body Animation Isn't Smooth"