2016-04-19 4 views
2

私はアニメーション化するキャンバスを持っています。私は、ウィンドウのサイズ変更イベントを聞いて、キャンバスのサイズを更新し、再帰的な描画を再開します。しかし、古いdraw()呼び出しが続行されているように見え、アニメーションが意図したよりも速く動くようになります。ここ はコードです:サイズ変更後にHTMLキャンバスの更新が何度も繰り返されます

HTML私は古いドロー()の呼び出しは、サイズ変更に彼らの再帰的な実行を継続防ぐことができますどのように

<canvas id="myCanvas" width="1000" height="1000"></canvas> 

CSS

* { 
    margin: 0; 
    padding: 0; 
} 

html, 
body { 
    width: 100%; 
    height: 100%; 
} 

canvas { 
    display: block; 
} 

はJavaScript

var canvas = document.getElementById("myCanvas"); 
var context = canvas.getContext('2d'); 
var frameCount = 0; 
var count = 0; 

var rectDistance = 100; 
var rectSize = 72; 
var rectOffset = (rectDistance - rectSize)/2; 
var angleSpeed = 1; 

var draw = function() { 
    count++; 

    var xCount = canvas.width/rectDistance; 
    var yCount = canvas.height/rectDistance; 

    context.fillStyle = "rgba(255,255,255,1)"; 
    context.fillRect(0, 0, canvas.width, canvas.height); 

    for (var i = 0; i < xCount; i++) { 
    for (var j = 0; j < yCount; j++) { 

     context.save(); 

     var r = Math.round(i/xCount * 255); 
     var g = Math.round(j/xCount * 255); 

     xPos = i * rectDistance + rectOffset + Math.sin(j + frameCount/20) * 10; 
     yPos = j * rectDistance + rectOffset + Math.cos(i + frameCount/20) * 10; 

     context.translate(xPos + rectSize/2, yPos + rectSize/2); 
     context.rotate(frameCount/100 * angleSpeed * Math.sin(frameCount/500) * 5); 

     context.fillStyle = "rgba(" + r + "," + g + ",0,1)"; 
     context.fillRect(-rectSize/2, -rectSize/2, rectSize, rectSize); 
     context.restore(); 
    } 
    } 

    frameCount = frameCount + 1; 
    requestAnimationFrame(draw); 
}; 

window.addEventListener('resize', function() { 
    setTimeout(function() { 
    resizeCanvas(); 
    }, 500); 
}, false); 

function resizeCanvas() { 
    canvas.width = window.innerWidth; 
    canvas.height = window.innerHeight; 

    draw(); 
} 

// count the calls of draw() per second -> it's increasing on window.resize 
function drawCalls() { 
    setTimeout(function() { 
    console.log("draw() called " + count + " times"); 
    count = 0; 
    drawCalls(); 
    }, 1000) 
} 
drawCalls(); 

// start the loop 
resizeCanvas(); 

?ここで

は、同じ問題を持つcodepenです:http://codepen.io/Sebkasanzew/pen/GZGZVP

+1

あなたがループを停止しない場合は、なぜあなたがresizeイベントでコールドロー? btwサイズ変更イベントは、おそらくrAFよりも高いレートで発生します。 [forked Pen](http://codepen.io/anon/pen/QNxEMN) – Kaiido

+0

resizeイベントの外にdraw()を呼び出すと問題が解決します。しかし、描かれたオブジェクトの作成は再び実行されません。しかし、これは少なくともこの例の問題を解決します。ありがとうございます。 別の方法はありませんか? – SebKas

+1

永遠に実行されているアニメーションのために、私は2つの別々のステップでそれをやっています:アプリのアップデート1と描画1。リサイズでは、アプリケーションの更新を呼び出すだけで、すべての変数がリセットされ、描画関数は各フレームの変数を消費します。 – Kaiido

答えて

3

あなたはsetTimeout()をキャンセルし忘れている - 私は次のことを示唆している:

var timer; 

window.addEventListener('resize', function() { 
    cancelAnimationFrame(timer);     // cancel previous request 
    timer = requestAnimationFrame(function() { // create a new request 
    resizeCanvas(); 
    }) 
}); 
+0

これは私が探していたものです。ありがとう! – SebKas

関連する問題