【问题标题】:How do I keep object location from being increased exponentially after each call to draw function?每次调用绘图函数后,如何防止对象位置呈指数增长?
【发布时间】:2012-08-06 23:22:47
【问题描述】:

每次点击都会在画布上创建类似烟花的效果的简单动画。问题是动画是用 setInterval(draw) 制作的,每次重新绘制画布时,每个粒子的位置都是 +=particle.speed。但是随着每次点击,粒子移动得越来越快,因为似乎每个粒子的速度都没有重置。

正如您在working example here: 上单击几下所看到的那样,第一次单击时,粒子移动非常(正确)缓慢,但随后每次单击时速度都会增加。

使用的JS也粘贴在下面,非常感谢任何帮助!

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");


    canvas.addEventListener("click", startdraw, false);


    //Lets resize the canvas to occupy the full page
    var W = window.innerWidth;
    var H = window.innerHeight;
    canvas.width = W;
    canvas.height = H;


    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, W, H);

    //global variables
    var radius;
    radius = 10;
    balls_amt = 20;
    balls = [];

    var locX = Math.round(Math.random()*W);
    var locY = Math.round(Math.random()*H);


    //ball constructor
    function ball(positionx,positiony,speedX,speedY)
    {   
        this.r = Math.round(Math.random()*255);
        this.g = Math.round(Math.random()*255);
        this.b = Math.round(Math.random()*255);
        this.a = Math.random();
        this.location = {
            x: positionx,
            y:positiony
        }
        this.speed = {
            x: -2+Math.random()*4, 
            y: -2+Math.random()*4
        };

    }




    function draw(){

        ctx.globalCompositeOperation = "source-over";
        //Lets reduce the opacity of the BG paint to give the final touch
        ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
        ctx.fillRect(0, 0, W, H);

        //Lets blend the particle with the BG
        //ctx.globalCompositeOperation = "lighter";

        for(var i = 0; i < balls.length; i++)
        {
            var p = balls[i];
            ctx.beginPath();
            ctx.arc(p.location.x, p.location.y, radius, Math.PI*2, false);
            ctx.fillStyle = "rgba("+p.r+","+p.g+","+p.b+", "+p.a+")";

            ctx.fill(); 
            var consolelogX = p.location.x;
            var consolelogY = p.location.y;
            p.location.x += p.speed.x;  
            p.location.y += p.speed.y;


        }
    }
    function startdraw(e){

        var posX = e.pageX;     //find the x position of the mouse
        var posY = e.pageY;     //find the y position of the mouse
        for(i=0;i<balls_amt;i++){
            balls.push(new ball(posX,posY));
        }

        setInterval(draw,20);
        //ball[1].speed.x;
    }   

【问题讨论】:

    标签: html canvas draw setinterval


    【解决方案1】:

    每次单击后调用startdraw,每次调用draw 方法时都会启动新的定期调用(setInterval)。所以在第二次点击之后你有 2 个平行间隔,在第三次点击之后你有 3 个平行间隔。 它不是指数级的,只是线性增加:)

    一个可能的脏修复: 引入一个interval 全局变量,并替换这一行:

             setInterval(draw,20);
    

    用这个:

            if (!interval) interval = setInterval(draw,20);
    

    或者更好的解决方案是在 onLoad 事件开始间隔。

    【讨论】:

      【解决方案2】:

      setInterval 将每 20 毫秒重复一次调用,并返回一个 ID。 您可以通过调用 clearInterval(ID) 来停止重复。

      var id = setInterval("alert('yo!');", 500);
      clearInterval(id);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-11
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 2019-03-07
        • 1970-01-01
        • 2019-07-13
        • 1970-01-01
        相关资源
        最近更新 更多