Canvas Taking too much time to move a picture up

Viewed 172

I am trying to move a image on <canvas> to jump.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Ball Jump</title>
</head>
<body>
<img src="./assets/ball.png" height="0px" width="0px" id="ball">
<br>


<br>
<canvas height="210px" width="350px" id="paper" onclick="play()"></canvas>
<script type="text/javascript" src="./main.js"></script
</body>
</html>

main.js

'use strict'
var paper = document.getElementById('paper');
var ball = document.getElementById('ball');
var brush = paper.getContext('2d');
brush.drawImage(dino, 0, 150, 70, 50);
var y = 150;
function play() {
up();
function up() {
if (y > 50) {
brush.clearRect(0, y-1, 70, y+50);
brush.drawImage(ball, 0, y, 70, 50);
y--;
}
else { clearInterval(jump); }
}
var jump = setInterval(up, 10);
function down() {
if (y < 150) {
brush.clearRect(0, y-1, 70, y+50);
brush.drawImage(ball, 0, y, 70, 50);
y++;
}
else { clearInterval(fall); }
}
var fall = setInterval(down, 10);
}

But the problem is that the ball is lagging and taking more time to go up, however it is coming down fine even if both functions are set to 10ms. Please help!!!

3 Answers

I think you should use requestAnimationFrame instead of setInterval

Example

const canvas = document.querySelector('#canvas');
const context = canvas.getContext('2d');

const image = new Image();
image.src = "https://picsum.photos/seed/picsum/50/50";

image.addEventListener("load", load);

function load(event) {
  loop();
}

let x = 0;
let y = 0;
let t = 0;
let r = 50;
const inc = Math.PI/90;

function loop() {
  const width = canvas.width;
  const height = canvas.height;
  context.clearRect(0, 0, width, height);
  context.drawImage(image, x, y, image.width, image.height);
  
  x = 100 + r * Math.cos(t);
  y = 100 + r * Math.sin(t);
  t = t + inc;
  
  requestAnimationFrame(loop);
}
<canvas height="400px" width="400px" id="canvas"></canvas>

I would not use multiple setInterval just one should do...
Here is an example:

var paper = document.getElementById('paper');
var brush = paper.getContext('2d');
var y = 100;
var speed = 1;

function draw() {
  if ((y < 10) || (y > 150)) {
    speed *= -1
  }
  y += speed
  brush.clearRect(0, 0, 160, 300);
  brush.fillRect(10, y, 10, 10);
}

function play() {
  setInterval(draw, 10);
}

draw()
<canvas height="160" width="300" id="paper" onclick="play()"></canvas>

In your code, both intervals are running simultaneously that could create the strange behavior you are seeing where the object is lagging and taking more time to go up but coming down is fine.

Instead of the two setInterval I introduced the variable speed that will determine the direction of the movement and we will "flip" it speed *= -1 when the position exceeds our boundaries

... with this pattern in your canvas animation it's easy to transition to requestAnimationFrame if performance becomes critical, but for simple practice code like this, setInterval works fine.

Related