简体   繁体   中英

setInterval doesn't work properly

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM