15

実験として、canvasオブジェクトを使用せずにJavaScriptでAS3のスプライト機能を複製しようとしています。絶対に配置されたdivを使用してcssプロパティを操作するのは簡単だと思いましたが、Chromeでは、アニメーションによって奇妙なアーティファクトが発生します(再描画の問題が原因のようです)。

何が間違っているのかわかりませんか?実際、コードは非常に単純です。これが私が試したが役に立たなかったいくつかのポイントです:

  • 比較的配置されたdivを使用する(絶対的に配置されるのではなく)。
  • マージンの使用(上部と左側のプロパティではなく)
  • オブジェクトを本体に直接追加する(コンテナdivに追加するのではなく)
  • setTimeoutの使用(requestAnimationFrameではなく)

ここで簡略化されたフィドルを見ることができます:http://jsfiddle.net/BVJYJ/2/

編集:http://jsfiddle.net/BVJYJ/4/

そして、ここであなたは私のブラウザでアーティファクトを見ることができます:

Chromeのアーティファクト

これは私のセットアップのバグである可能性があります(Windows 7 64ビット、Chrome 21.0.1180.75)。他のブラウザはこの動作を示しません。誰かが私が間違っている可能性があることについてコメントしていただければ幸いです。回避策ではなく、この背後にある理由についてもっと興味があります。とはいえ、どんな説明でも大歓迎です。:)

編集:サンプルコードにバグがあり、RAFが使用されているという印象を受けていてもsetTimeoutを使用することになりました。requestAnimationFrameは基本的な変換の問題を解決しますが、問題は回転などのCSS変換に残ります。

回転変換を使用したChromeのアーティファクト。

4

3 に答える 3

28

liteAccordionプラグインでも同じ問題が発生しました。http://jsfiddle.net/ZPQBp/1/でわかるように、アニメーション化する要素で背面の可視性を非表示に設定することで修正できます。

于 2012-08-18T23:56:28.783 に答える
3

いくつかの研究は、setTimeoutさまざまな理由で問題を引き起こす可能性があることを示しています。あなたは本当に使うべきですrequestAnimationFrame

タイマーはミリ秒まで正確ではありません。一般的なタイマーの解像度は次のとおりです1

  • InternetExplorer8以前のタイマー解像度は15.625msです。
  • InternetExplorer9以降のタイマー解像度は4msです。Firefox
  • とSafariのタイマー解像度は約10msです。
  • Chromeのタイマー解像度は4ミリ秒です。

バージョン9より前のInternetExplorerのタイマー解像度は15.625ms1であるため、0〜15の値は0または15のいずれかになりますが、それ以外の値はありません。Internet Explorer 9はタイマーの解像度を4ミリ秒に改善しましたが、アニメーションに関してはまだそれほど具体的ではありません。

Chromeのタイマー解像度は4ミリ秒ですが、FirefoxとSafariのタイマー解像度は10ミリ秒です。そのため、最適な表示のために間隔を設定しても、希望するタイミングに近づいています。

参照:http ://www.nczonline.net/blog/2011/05/03/better-javascript-animations-with-requestanimationframe/

また

setTimeoutブラウザで他に何が起こっているかを考慮していません。ページがタブの後ろに隠れて、必要のないときにCPUを占有したり、アニメーション自体がページからスクロールされて更新呼び出しが不要になったりする可能性があります。Chromeは非表示のタブでsetIntervalとsetTimeoutを1fpsに抑制しますが、これはすべてのブラウザーで信頼できるわけではありません。

第二setTimeoutに、コンピュータが更新できるときではなく、必要なときにだけ画面を更新します。つまり、貧弱なブラウザは、画面全体を再描画するときにアニメーションの再描画を調整する必要があり、アニメーションのフレームレートが画面の再描画と同期していない場合は、より多くの処理能力を消費する可能性があります。これは、CPU使用率が高くなり、コンピューターのファンが作動したり、モバイルデバイスのバッテリーを消耗したりすることを意味します。Nicolas Zakasは、関連 記事でタイマーの解像度がアニメーションに与える影響を説明する優れた仕事をしています。

参照: http: //creativejs.com/resources/requestanimationframe/

于 2012-08-12T19:16:24.610 に答える
1

これは、サブピクセルの配置と関係があります。最も近いピクセルに四捨五入すると、これらのレンダリングエラーは表示されません。

thisRef.block.style.left = Math.round((x + (mouseX - ox - x) * .125)) + "px";
thisRef.block.style.top = Math.round((y + (mouseY - oy - y) * .125)) + "px";
于 2012-08-12T19:22:15.543 に答える