Reputation: 35
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
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
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
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