0

私は最近canvasで遊んでいて、今日からsetIntervalを使用して定期的に更新/アニメーション化する作業を開始しました。これがCPUにとってどのように重く、すべての動作が遅くなるかを見て驚いた。オンラインで例を見ると、私のやり方に何か問題があると確信しています。次に、やりたいことを最大限に単純化しました(画像ではなく長方形で遊んだり、オブジェクトを多用しすぎたりしないなど)が、それでも同じ問題が発生しました。

私は2つの長方形の上に白いフラッシュ(12fps)を取得しようとしていました...だから何も複雑ではありません...

これが私のコードです。

function Canvas(name){
this.ctx=document.getElementById(name).getContext('2d');
this.canvas=this.ctx.canvas;
this.width=this.canvas.width;
this.height=this.canvas.height;
this.layers=new Array();

this.draw = function() {
this.canvas.width = this.canvas.width;
    this.ctx.beginPath();
    this.ctx.rect(0,0,this.width,this.height);
    this.ctx.closePath();
    this.ctx.fillStyle="#eaeaea";
    this.ctx.fill();
    this.ctx.beginPath();
    this.ctx.rect(250,50,300,250);
    this.ctx.closePath();
    this.ctx.fillStyle="#ff0000";
    this.ctx.fill();

    intensity=Math.random();
    this.flash(intensity);
 };

this.flash = function(intensity) {
    this.ctx.globalAlpha = intensity;
    this.ctx.beginPath();
    this.ctx.rect(0,0,this.width,this.height);
    this.ctx.closePath();
    this.ctx.fillStyle="#fff";
    this.ctx.fill();
    this.ctx.globalAlpha = 1;
    setInterval(this.draw.bind(this),1000);
};

function initCanvas(){
mycanvas=new Canvas('myCanvas');
mycanvas.draw();
}

$(document).ready(function() {
    initCanvas();
});

見つかった解決策:

setIntervalの代わりにsetTimeoutを使用します。

4

3 に答える 3

2

setInterval関数で使用し続けるため、大量のメモリリークが発生しflashます。イベントのシーケンスを見てみましょう

  • mycanvasオブジェクトが作成されました
  • 描く()
  • ドローコールフラッシュ
  • flashは、draw毎秒呼び出す間隔を設定します
  • ドローコールが点滅し、別の間隔を設定します
  • 呼び出しの間隔が多くなるまで、プロセスが繰り返されますdraw

それを解決するには、で使用setTimeoutflashます。したがって、1秒後に呼び出しdraw、1秒後に呼び出してから再度flash呼び出します。drawまた、1000msでは12fpsにはなりません。1000/12になります。

また、を使用ctx.closePath();して開いたパスを閉じますbeginPath()

Canvasまた、。で関数を閉じたことはありません}

これがデモです

于 2012-07-17T12:04:16.447 に答える
2

開いたすべてのパスを閉じます。

this.draw = function() {
    this.canvas.width = this.canvas.width;
    this.ctx.beginPath();
    this.ctx.rect(0,0,this.width,this.height);
    this.ctx.closePath();    //Closing
    this.ctx.fillStyle="#eaeaea";
    this.ctx.fill();
    this.ctx.beginPath();
    this.ctx.rect(250,50,300,250);
    this.ctx.closePath();    //Closing
    this.ctx.fillStyle="#ff0000";
    this.ctx.fill();

    this.flash(40);
};

this.flash = function(intensity) {
    this.ctx.globalAlpha = intensity;
    this.ctx.beginPath();
    this.ctx.rect(0,0,this.width,this.height);
    this.ctx.closePath();    //Closing
    this.ctx.fillStyle="#fff";
    this.ctx.fill();
    this.ctx.globalAlpha = 1;
    setInterval(this.draw.bind(this),1000);
};
于 2012-07-17T11:59:30.910 に答える
0

これがもう関係あるかどうかはわかりませんが、私は自分が似たような状況にあることに気づき、さらに良い答えを出したいと思いました. を使用requestAnimationFrame(yourLoop)します。特にゲームの場合は、高速でパフォーマンスが向上します。 http://www.paulirish.com/2011/requestanimationframe-for-smart-animation/

于 2016-04-20T01:59:41.477 に答える