web-dev-qa-db-ja.com

Webkitアニメーションが画面にジャンクピクセルを残している

次のコードは、画面に白いボックスを配置します。これをiPadで実行する場合(ピクセルを調整してiPhoneでも実行できます)、ボックスをタッチすると、画面からスクートされ、下部のエッジに沿って白っぽいピクセルの跡が残ります。

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-height, user-scalable=no, maximum-scale=1, minimum-scale=1" />
    <title>Line Bug Demo</title>
    <style>
body {
  background: black;
}
.panel {
  background: white;
  position: absolute;
  z-index: 2;
  width: 1000px;
  height: 500px;
  top: 34px;
  left: 12px;
  -webkit-border-radius: 20px;
  -webkit-transition: left 0.333s ease-in-out;
}
.panel.hide {
  left: -1000px;
}
    </style>
  </head>
  <body>
    <div class="panel" onclick="this.setAttribute('class', 'panel hide')"></div>
  </body>
</html>

バグを取得するための鍵は、境界線の半径を使用し、アニメーションを実行することです。画面からそれをポップするだけの場合、トレイルはありません。国境の半径がない場合、歩道はありません。

これまでに見つけた回避策は次のとおりです。

.panel.hide { -webkit-border-radius: 0; }

醜く、実際のアプリケーションでは実用的ではありません。パネルを内側と外側の両方でアニメーション化しているので、画面上にある角を丸くしたいのです。

別の:

.panel { -webkit-transform: translateZ(0); }

これにより、パネルがハードウェアパイプラインに配置され、合成が正しく行われます。これはこの簡単なデモで機能しますが、実際のWebアプリでハードウェアパイプラインを使用すると、メモリ不足エラーが発生します。 (抜本的で巨大な、即時の多様性のうち。)

この道を取り除く方法に関する他のアイデアはありますか?

35
Joshua Smith

ソリューション

box-shadow: 0 0 1px rgba(0, 0, 0, 0.05);

ボックスの背景色が目立ちすぎる場合は、box-shadowの色として使用できます。

または、この Chromeでの同様の問題についての回答 (チップオフのコメントで Sebastian に感謝)に従って、次のことを試してください:

outline: 1px solid transparent;

どうしたの?

他の場所で かなり長い説明 を指定しましたが、ここに短いバージョンがあります。パフォーマンス上の理由から、WebKitは、変更されたと思われるページの部分のみを再描画します。ただし、境界線半径のiOS(7より前)のSafari実装では、ボックスの計算された寸法を数ピクセル超えたアンチエイリアスが行われます。 WebKitはこれらのピクセルを認識しないため、再描画されません。代わりに、それらは取り残され、各アニメーションフレームに蓄積されます。

通常の解決策は、他の回答で提案したように、その要素にハードウェアアクセラレーションを要求して、別のレイヤーとしてペイントされるようにすることです。ただし、小さすぎる要素や大きすぎる要素が多すぎると、多くのタイルがGPUにプッシュされ、パフォーマンスに明らかな影響が及びます。

box-shadowを使用すると、問題がより直接的に解決されます。これにより、ボックスの再描画の寸法が拡張され、WebKitが余計なピクセルを再描画するようになります。モバイルブラウザーでのbox-shadowの既知のパフォーマンスへの影響は、使用されるぼかし半径に直接関連しているため、1ピクセルの影はほとんど効果がないはずです。

58
Jordan Gray

私がすること:

  • _-webkit-backface-visibility: hidden_
  • -webkit-transform:translateX(left value here) //またはtranslate-3d(x,y,z)でアニメートします左は無効にする必要があります [*]

parentでハードウェアアクセラレーションを有効にしても違いが生じるかどうかを確認してください。

強制的に再描画する簡単な方法もあります。それらについての情報も必要な場合はお知らせください。

[*] 3D変換に依存することはハックであり、注意して使用する必要があります。これは、GPUとメモリの間のトレードオフです。場合によっては、アニメーションのジャンクまたはメモリの問題を引き起こす可能性があります(モバイル-大きな領域でGPUアクセラレーションを強制するなど)。

CSS _will-change_プロパティは、事前に最適化できるプロパティをマークするための正しい場所になります。

8
Rafal Pastuszak