0

クリックするたびにキャンバスに花火のような効果を生み出すシンプルなアニメーション。問題は、アニメーションがsetInterval(draw)で作成され、キャンバスが再描画されるたびに、各パーティクルの位置が+=particle.speedになることです。しかし、クリックするたびに、各パーティクルの速度がリセットされていないように見えるため、パーティクルはどんどん速く移動します。

ここでの作業例を数回クリックするとわかるように、最初のクリックでパーティクルは非常に(正しく)ゆっくりと移動しますが、その後のクリックごとに速度が上がります。

使用した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;
    }   
4

2 に答える 2

0

setIntervalは、20ミリ秒ごとに呼び出しを繰り返し、IDを返します。clearInterval(ID)を呼び出すことで、繰り返しを停止できます。

var id = setInterval("alert('yo!');", 500);
clearInterval(id);
于 2012-08-05T18:21:34.280 に答える
0

クリックstartdrawが呼び出されるたびsetIntervalに、メソッドの新しい定期的な呼び出し()が開始されdrawます。したがって、2回目のクリックの後、2つの平行な間隔があり、3回目のクリックの後、3つの平行な間隔があります。指数関数的にではなく、直線的に増加するだけです:)

考えられるダーティな修正:intervalグローバル変数を導入し、次の行を置き換えます。

         setInterval(draw,20);

これで:

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

または、より良い解決策は、onLoadイベントで間隔を開始することです。

于 2012-08-06T15:22:47.560 に答える