36

この 1 週間、友人がブラウザで SVG ベースのスプライト シートを試すのを手伝いました。私たちは、ブラウザで高品質のアニメーション グラフィックを準備、公開、実行するための理想的なワークフローを考え出したいと考えていました。そのため、小さなスマートフォン画面、タブレット、Retina ディスプレイ、およびデスクトップ ブラウザで機能するアニメーション データの単一ソースを用意することが理想的です。

理論的には、(ベクターベースの) SVG が理想的ですが、SVG は通常あまり使用されないため、テストすることにしました。アイデアは、SMIL SVG (SVG ベースのアニメーションではない) を使用するのではなく、代わりにアニメーション スプライト シートを作成することでした (ラスター データ PNG/JPG で通常行うように) が、純粋なベクター、つまり SVG でこれを行います。少し大きかったですが、これが機能する場合は、さらに最適化されたものでも機能します。

さらに、フレーム単位のベクター アニメーションは、ワークフローに最適です。Flash エディターを使用してアニメーションを作成し、SVG スプライト シートにエクスポートできます。

とにかく、結果は驚くほどうまく機能しますが、一部の領域では失敗します (テスト目的で、Webkit ベースのブラウザー、つまり Safari、Chrome、iOS のモバイル Safari、および Android ICS のみで動作したことに注意してください)。

CSS では、このようなスプライト シートのハードウェア アクセラレーションをトリガーするのは非常に簡単です (少なくともキーフレームとステップを備えた最新のブラウザーでは)。これを行うだけです。

background-image: url(my.svg);
-webkit-animation: walk 1s steps(12, end) infinite; 

ここに示すキーフレームベースのアニメーションを呼び出すには:

@-webkit-keyframes walk {
    from { -webkit-transform: translate3d(0, 0, 0); }
    to { -webkit-transform: translate3d(-100%, 0, 0); }          
}

translate3d を使用すると GPU が起動し、iOS モバイル Safari と Android ICS ブラウザーで全体がハードウェア アクセラレーションされるはずです。

驚くべきことに、これは力ずくの手法であり、かなり大きなベクター アニメーション (テストでは 600x600 ピクセル) であることを考えると、すべてが飛びます。しかし、それは完璧ではありません.離陸する前にSafariでちらつきます. また、ICS ブラウザでは常にちらつきが発生するため、実際には使用できません。

そのため、次のようなちらつきを取り除くために通常のトリックを試しました。

-webkit-transform: translateZ(0);    
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;

しかし、それはうまくいきませんでした。そこで、SVG をメモリ内で動的にラスタライズし、-webkit-transform: scale3d(1, 1, 0)を使用してテクスチャとして使用しようとしましたが、うまくいきませんでした。

最後に、SVG を同じサイズのレンダリングされた PNG/JPG スプライト シートに置き換えましたが、複雑なベクトルはブラウザーには大きすぎると考えました。同じ問題なので、SVG レンダリングではなく、ブラウザの描画の問題です。それをさらに証明するのは、アニメーションを 1FPS まで遅くすると、ちらつきがまだ続くことです。

画像が GPU には大きすぎますか? ブラウザー (特にモバイル) で快適に描画/アニメーション化できるパフォーマンスの限界に達しましたか?

ちらつきを潜在的に取り除く方法に関するアイデア/ハックを本当に感謝します(特に、パフォーマンスが非常に高速であるため)。これはまさに有望な技術です - さまざまな画面サイズに適応する高性能ブラウザ アニメーション - HTML5 の聖杯;)

次のようないくつかの最適化を使用して

<svg preserveAspectRatio="xMinYMax slice" viewBox="0 0 600 50">

また、いくつかの CSS マジックにより、SVG をコンテナーに完全に適合させ、単一の CSS クラスからサイズを変更することができます。それは本当に驚異的に機能しますが、残念なことにちらつきがあります。

とにかく -ここでそれについてもっと読んでください。あなたも試してみることができます。

4

2 に答える 2

3

かなりクールなアイデア。

フレームのzindexを変更して、画像を重ねて表示するのはどうですか?再描画中に最後のフレームがまだ表示されているため、これによりちらつきが解決される可能性があります。したがって、最新のフレームのzindex値を増やし続けるだけです。もちろん、それには制限があり、zindexを再度リセットする必要がありますが、ちらつきの削減に大きな影響を与える可能性があります。

于 2012-10-16T13:46:31.760 に答える
1

確認するための ICS はここにはありませんが、iPhone 5 の iOS 6 と Galaxy Nexus の Jelly Bean 4.1.1 では、アニメーションは非常にスムーズに見えます。そしてまた落ち着きます。

これは、私が大きなキャンバスにレンダリングし、それを画面の周りに変換していた同様の問題を思い出させました(キャンバスの大部分は常にオフスクリーンで)。

当時の私のブラックボックス分析は、ブラウザーが画面外のコンテンツをレンダリングするのではなく、表示されるまで待機するという最適化であることが示唆されました。これは、大きな画像を表示してハードウェアで高速化するという目的を完全に無効にしました。

私の「解決策」は -webkit-transform でした: 画像全体を十分に小さく縮小して、すべてが画面に収まるように (ブラウザは画像全体をレンダリングする以外に選択肢がありません)、レンダリングさせてから、欲しかったサイズ。

(余談ですが、このハッカーをユーザーから隠すために、最初に opacity: 0 を設定して事前レンダリングが表示されないように実験しましたが、これはオフスクリーン レンダリングと同じ効果があったようです - 最適化されました。最後に、不透明度を非常に低く設定し、ほぼ不透明な「読み込み中」メッセージで覆いました。つまり、背景のレンダリングは肉眼では見えませんでしたが、ブラウザには最適化するための絶対的な可視/不可視がありませんでした。やり過ぎでしたが、私のセットアップではうまくいったようです。)

同様の手法があなたに役立つかどうかを知りたいと思います。

于 2012-11-03T22:29:48.477 に答える