5

私は最近、HTML5/Canvas の作業を開始し、Firefox で作業していたことを試すことにするまで、Chrome で作業をテストしながら非常に満足してビジネスに取り組んでいました...あまりうまくいきません。

これは私がやっていることの骨の折れる例です。基本的な requestAnimationFrame shim を設定すると、メイン ループがキャンバスをクリアし、オブジェクトを更新して描画します。簡単なことですが、このような例はどこにでもあります。

function loop() {
  canvas.width = canvas.width;

  requestAnimFrame(loop);

  rR.update();
  rG.update();
  rB.update();
  rY.update();

  rR.draw();
  rG.draw(); 
  rB.draw();
  rY.draw();
}

function Rect(color, x, y, speedX, speedY) {
  this.x = x;
  this.y = y;
  this.color = color;
  this.speedX = speedX;
  this.speedY = speedY;
}

Rect.prototype.draw = function () {
  context.fillStyle = this.color;
  context.beginPath();
  context.rect(this.x, this.y, 10, 10);
  context.closePath();
  context.fill();
};

Rect.prototype.update = function () {
  if (this.x < 0 || this.x > canvas.width) this.speedX = -this.speedX;
  if (this.y < 0 || this.y > canvas.height) this.speedY = -this.speedY;

  this.x += this.speedX;
  this.y += this.speedY;
};

var rR = new Rect("#FF0000", canvas.width/2, canvas.height/2, 2, 2);
var rG = new Rect("#00FF00", canvas.width/2, canvas.height/2, -2, -2);
var rB = new Rect("#0000FF", canvas.width/2, canvas.height/2, 2, -2); 
var rY = new Rect("#FFFF00", canvas.width/2, canvas.height/2, -2, 2);

http://jsfiddle.net/Polaris666/psDM9/3/

Chrome でこれをテストしたところ、見栄えはよくなりましたが、Firefox ではかなり単純なタスクのように、多くの吃音やティアリングが見られました。

同様の質問を見つけましたが、明確な解決策があるものはありません。これはFirefoxのことですか?Webkit ブラウザーはこれを行うのに優れているだけですか? あきらめて、ブラウザの将来のバージョンで修正されることを願うべきでしょうか? それとも、それは私の特定の設定ですか?FireFox 17.0.1 で Windows 7 64 ビットを使用しています。

どんな助けでも大歓迎です。

4

3 に答える 3

1

@HakanEnsari が提供するソリューションは機能しているようです。私はその理由に興味があり、彼のバージョンのコードがキャンバス全体をクリアしていないことが原因であることがわかりました。個々の 10x10 Rects のみをクリアし、残りのキャンバスはそのままにします。

これは少し入り込み、他にも便利なキャンバスのパフォーマンスに関するヒントがたくさんあります: http://www.html5rocks.com/en/tutorials/canvas/performance/#toc-render-diff

だからあなたはこれが欲しい:

  function loop() {
    // get rid of this
    //canvas.width = canvas.width; 

    requestAnimFrame(loop);

個々の四角形をクリアするだけです

Rect.prototype.update = function () {  
    if (this.x < 0 || this.x > canvas.width) this.speedX = -this.speedX;
    if (this.y < 0 || this.y > canvas.height) this.speedY = -this.speedY;

    // clear just the rect
    context.clearRect(this.x, this.y, 10, 10);

    this.x += this.speedX;
    this.y += this.speedY;
  };

(微調整されたフィドル: http://jsfiddle.net/shaunwest/B7z2d/1/ )

于 2013-07-16T22:22:03.490 に答える
0

どうやら、キャンバスをクリアするとcanvas.width = canvas.width;Safariでラグが発生したようです(バージョン5.1.9でブラウジングしています)。

画面をクリアするこの方法を使用したことはありません。代わりに、次の方法を使用します。

context.clearRect(0,0, canvas.width, canvas.height);

試してみると、もう遅れることはありません。jsfiddleを参照してください。


これは、キャンバスをクリアする最速の方法です。反対に、個々の要素をクリアするには、次のことを行う必要があります。

  1. すべての要素の位置を追跡する
  2. clearRect再描画するすべての要素に対して呼び出しを実行します

また、長方形以外の形状では機能しません(clearSphereまたはclearPathメソッドがないため)。

于 2013-07-16T22:40:11.530 に答える