Gyan Prakash
Gyan Prakash

Reputation: 35

Canvas Taking too much time to move a picture up

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!!!

Upvotes: 3

Views: 294

Answers (3)

Shuky Capon
Shuky Capon

Reputation: 785

For animations running smoothly on the browser, you should really use a requestAnimationFrame loop instead of setInterval

checkout the example here: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations

here is why: Why is requestAnimationFrame better than setInterval or setTimeout.

Upvotes: 1

Helder Sepulveda
Helder Sepulveda

Reputation: 17594

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.

Upvotes: 2

J&#243;zef Podlecki
J&#243;zef Podlecki

Reputation: 11283

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>

Upvotes: 3

Related Questions