I have a image and I'm trying to animate it through setInterval()
. My aim is to move the image up by a certain pixel only when the user clicks on the Canvas
else the image should be moving downwards.Everything goes well but the timer increases the speed for every onclick()
my canvas tag
<canvas id="myCanvas" width="400" height="600" onclick=init()></canvas>
java script:
function init()
{
function draw1()
{
context.clearRect(0,0,400,600);
img_y = img_y - 40;
context.drawImage(image1,img_x,img_y);
}
function move()
{
context.clearRect(0,0,400,600);
img_y = img_y + 7;
context.drawImage(image1,img_x,img_y);
}
draw1();
setInterval(move,70);
}
My animation starts when the user clicks the Canvas
of my game. When I click the Canvas
for the second time or so,the animation speed increases. What is wrong with my logic?
Your problem is that each click ADDS an interval. So your code basically runs more times than you want (making your animation faster). Make sure to clear the interval before starting a new one. Try the following ( docs ):
window.myTimer = '';
function init()
{
function draw1()
{
context.clearRect(0,0,400,600);
img_y = img_y - 40;
context.drawImage(image1,img_x,img_y);
}
function move()
{
context.clearRect(0,0,400,600);
img_y = img_y + 7;
context.drawImage(image1,img_x,img_y);
}
draw1();
window.clearInterval(window.myTimer); // clear previous interval
window.myTimer = setInterval(move,70); // set it again
}
As @Pointy pointed out,, you are increasing the 'speed' every click, because you are creating a new interval which is calling that same function.
Consider either clearing the interval and making a new one each time : window.clearInterval(intervalId);
OR
implementing a bool within your function which will prevent its movement until click.
You are mixing up the code that initiates movement with the code that moves the object up. They need to be separate functions.
<canvas id="myCanvas" width="400" height="600" onclick="moveUp"></canvas>
JS:
var movement = 7, timer;
function animate() {
context.clearRect(0, 0, 400, 600);
img_y += 7;
context.drawImage(image1, img_x, img_y);
}
function moveUp() {
// no need to redraw the image here as it will be drawn at the next frame anyway
img_y -= 40;
}
function init() { // call this when you want the main animation to start
if (timer) { // if timer variable already exists
clearInterval(timer); // clear the corresponding interval
timer = null; // and also clear the variable itself
}
timer = setInterval(animate, 70);
}
(This code clears the timer before setting it, in case, for some reason, init
is called more than once.)
You could also work with the onmouseup, onmousedown events, letting it move as long mouse is pressed, and stop moving when mouse is no longer pressed. This way you can create and remove the interval on both events
var interval; function startInterval() { interval = setInterval(animation.move.bind(animation), 70); } function stopInterval() { clearInterval(interval); } var animation = { old: undefined, x: 0, y: 0, context: undefined, move: function() { this.y += 10; animation.draw(); }, draw: function() { if (typeof animation.context === 'undefined') { var el = document.getElementById('ctx'); animation.context = el.getContext('2d'); } var context = animation.context; if (typeof animation.old !== 'undefined') { context.clearRect(animation.old.x, animation.old.y, 10, 10); } animation.old = { x: animation.x, y: animation.y }; context.fillStyle = "#FF0000"; context.fillRect(animation.old.x, animation.old.y, 10, 10); } };
<canvas id="ctx" width="300" height="300" onmousedown="startInterval()" onmouseup="stopInterval()"></canvas>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.