0

画像の上の長方形の塗りつぶしを (消しゴムのように) クリアするアニメーションを作成しようとしています。円がアニメーション化されると、それがカバーしていたすべての領域がクリアされます。

globalCompositeOperation を使用してこれを行うことはできますが、アニメーションを遅くしようとしてもうまくいきません。setTimeout 関数を試しています。アニメーションが遅くならない理由はありますか? 私が知っていることはすべて試しましたが、助けや代替案があれば大歓迎です。

また、 setTimeout(func(),time in ms) 関数を使用しようとすると、画像も削除されます。

function compose()
//adds the purple fill rectangle, adds the image and then animates the circle
{
context.globalCompositeOperation = 'destination-atop';
fillRectangle(100, 100, 900, 500);
context.globalCompositeOperation = 'destination-atop';
context.drawImage(img, destX, destY);
for (var a = 0; a < 1000; a++) {

    if (x + dx + radius > width || x + dx < radius) {
        dx = -dx;
    }
    if (y + dy + radius > height || y + dy < radius) {
        dy = -dy;
    }
    x = x + dx;
    y = y + dy;
    //setTimeout("circle(x,y)", 1);
    circle(x, y);
    }
context.globalCompositeOperation = 'destination-atop';
context.drawImage(img, destX, destY
}
function circle(x, y)
{// this simply animates the circle over the purple fill
context.globalCompositeOperation = 'destination-out';
context.fillStyle = "#444444";
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, true);
context.closePath();
context.fill(); //setTimeout("context.fill();",3);
context.globalCompositeOperation = 'destination-atop';
}

完全なコード:

キャンバス テスト

        var t;
        //holds the drawing context of the canvas element
        var context;

        //size of canvas
        var width = 600;
        var height = 300;

        //position of the ball
        var x = 150;
        var y = 150;

        //speed of the ball
        var dx = 2;
        var dy = 2;

        //ball radius
        var radius = 10;
        var compositeType = ['xor'];
        var destX = 0;
        var destY = 0;
        var img = new Image();
        img.src = 'nexus.jpg';
        function init() {
            context = document.getElementById("canvas").getContext("2d");

            compose();

        }
        function compose()
        //adds the purple fill rectangle, adds the image and then animates the circle
        {
            context.globalCompositeOperation = 'destination-atop';
            fillRectangle(0, 0, 900, 600);
            context.globalCompositeOperation = 'destination-atop';
            context.drawImage(img, destX, destY);
            var cnt = 0;

            function runIteration() {
                if (x + dx + radius > width || x + dx < radius) {
                    dx = -dx;
                }
                if (y + dy + radius > height || y + dy < radius) {
                    dy = -dy;
                }
                x = x + dx;
                y = y + dy;
                circle(x, y);
                cnt++;
                if (cnt < 10000) {
                    context.globalCompositeOperation = 'destination-atop';
                    context.drawImage(img, destX, destY);
                    setTimeout(runIteration, 10);

                }
            }
            runIteration();

        }

        function fillRectangle(x, y, w, h)
        {
            context.fillStyle = "#550055";
            context.fillRect(x, y, w, h);
        }
        //draws the circle with center location at x,y
        function circle(x, y) {
            // context.globalAlpha=0.1;
            context.globalCompositeOperation = 'destination-out';

            context.fillStyle = "#444444";
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI, true);
            context.closePath();
            context.fill(); //setTimeout("context.fill();",3);

            context.globalCompositeOperation = 'destination-atop';
        }

        //draws a rectangle with width(w) & height(h) with top left corner at (x,y)
        function rectangle(x, y, w, h) {
            context.fillStyle = "#000000";
            context.strokeRect(x, y, w, h);
        }
        //clears the whole canvas
        function clear() {
            context.clearRect(0, 0, 800, 300);
        }
        window.addEventListener("load", init, true);
    </script>

4

1 に答える 1

0

の使用はsetTimeout()適切な方法ではありません。 setTimeout()非同期関数です。すぐに戻り、後で作業するようにスケジュールします。

コードが記述されると、for ループ全体がすぐに実行され、1000setTimeoutタイマーが設定されます。これによりアニメーションが遅くなることはありませんが、開始がわずかに遅れるだけです。

アニメーションを遅くするには、for ループの各反復を asetTimeout()で実行し、そのタイムアウトが終了して実行されたらsetTimeout()、ループの次の反復で次をスケジュールするようにコードを再構築する必要があります。次のようになります。

function compose()
//adds the purple fill rectangle, adds the image and then animates the circle
{
    context.globalCompositeOperation = 'destination-atop';
    fillRectangle(100, 100, 900, 500);
    context.globalCompositeOperation = 'destination-atop';
    context.drawImage(img, destX, destY);
    var cnt = 0;

    function runIteration() {
        if (x + dx + radius > width || x + dx < radius) {
            dx = -dx;
        }
        if (y + dy + radius > height || y + dy < radius) {
            dy = -dy;
        }
        x = x + dx;
        y = y + dy;
        circle(x, y);
        cnt++;
        if (cnt < 1000) {
            setTimeout(runIteration, 10);
        }
    }
    runIteration();
}
于 2011-11-10T03:02:23.150 に答える