CSS アニメーションを作成するための構文を学ぶことはできますが、美しく滑らかなアニメーションを作成するには、より詳細な注意を払う必要があるかもしれません。アニメーションが重視されるようになった現在では、コードのアニメーションのタイミングやエラー発生時のさまざまなデバッグ方法を正確に調整することが重要です。この問題を自分で解決してから整理してください。
複数のアニメーションを同時に実行する場合、アニメーションを少しずらして実行する必要があります。現時点ではアニメーション遅延を使用できますが、ユーザーがページにアクセスしたときに一部の要素が動いていないのを確認するために必ずしも遅延を待つ必要はありません。
このとき、アニメーション遅延を負の数に設定すると、数秒スキップして直接アニメーションに入り、モニターが表示されているときにすべてのアニメーションが実行されます。この方法は、アニメーションのキーフレーム値が同じで、モーション遅延だけが異なる場合に便利です。
もちろん、この概念をデバッグに使用することも良い選択です。アニメーションの再生状態を設定し、さまざまな負の時間の遅延を調整します。動作中のアニメーションのさまざまな一時停止状態が表示されます。
.thing { animation: move 2s linear infinite alternate; animation-play-state: paused; animation-delay: -1s;}
例:
以下のこの楽しいデモでは、2 台のロボットがわずかに異なる時間で動きます。これにより、アニメーションがよりわかりやすくなります。自然。ここでは、紫色のロボットがアニメーションを実行するために負の遅延も使用しています。これにより、ユーザーがページを見たときにロボットはすでに動いています。
最高のパフォーマンスを得るには、マージン/上/左などの再描画のコストを節約するために、移動と変換にも変換を使用する必要があります。 Paul Lewis は、これらのコストを表す CSS トリガーのリストを作成しました。移動したい物体に複数の変形がある場合、それに対応する問題がいくつか発生します。
大きな問題の 1 つはその順序です。変換は予想されるように同時に実行されるのではなく、順序立てて実行されます。一番右にあるものを最初に実行し、次に内側に実行します。たとえば、以下のコードでは、最初にスケーリング (scale) が実行され、次に変換 (translate)、最後に回転 (rotate) が実行されます。
@keyframes foo { to { /* 第三 第二 第一 */ transform: rotate(90deg) translateX(30px) scale(1.5); }}
ただし、ほとんどの場合、これは理想的ではなく、同時に移動したい場合もあります。さらに、次のように、複数のキーフレームで同時に変換値を使用し始めると、事態はさらに複雑になります。
@keyframes foo { 30% { transform: rotateY(360deg); } 65% { transform: translateY(-30px) rotateY(-360deg) scale(1.5); } 90% { transform: translateY(10px) scale(0.75); }}
何か奇妙で予期せぬことが起こりました。残念ながら、この問題に対する通常の解決策は、複数の < div > をネストし、それぞれに翻訳を付けて、競合を起こさないようにすることです。
次のようにします。
もちろん、行列変換を使用する (手動でコードを作成するのは直感的ではありません) か、GreenSock のような JavaScript アニメーション API を使用するなど、いくつかの回避策があります。複数の変換を挿入するには、順序付けされたシーケンスが必要です。
より多くの div を使用すると、SVG のいくつかの問題を解決できる場合があります。たとえば、Safari では、アニメーション内で透明度 (opacity) と変形 (transform) を同時に宣言することはできません。そうしないと、いずれか 1 つが確実に無効になります。
2015 年 8 月初旬に、Canary バージョンの Chrome に独立変換宣言 (独立変換宣言) が追加されました。これは、より多くの変換効果を使用することを心配する必要がなく、rotate、translate、scale を個別に宣言できることを意味します。
## DevTools タイム コントローラーを使用する
Chrome と Firefox の両方に、アニメーション速度を制御できるスライダー、一時停止ボタン、いくつかの単純な数値 UI テスト (UI) など、アニメーションのデバッグに特化したツールがいくつかあります。イージング値を操作するため)、速度を落として一時停止してアニメーションの特別なポイントを観察することは、CSS アニメーションの非常に便利なデバッグ方法です。
どちらのブラウザも、Lea Verou の cubic-bezier.com のビジュアル GUI を使用します。したがって、テキスト エディターでコードを調整および変更するために cubic-bezier.com に繰り返しアクセスする必要はありません。
これらのツールを使用すると、アニメーションをより直感的に調整できます。
Chrome と Firefox はアニメーション時間 (加速または減速) を制御できるだけでなく、自動定義アニメーションも使用します。複数の要素を同時に視聴できる、より高度なタイムライン ツールも Chrome でリリースされようとしています (YouTube ビデオをバイパスする必要があります)。結局のところ、一度に 1 つの要素しか処理できないことは、アニメーション調整において大きな制限となります。
もう 1 つの問題は、アニメーションが短時間存在する場合、それをキャプチャするのが難しいことです。そのため、通常は、アニメーションを実行せずにデバッグを続行できるように、animation-iteration-count:finity を設定する必要があります。時間を気にしすぎます。
もちろん、ブラウザでアニメーションの速度を落として調整したり再生したりするのに役立つ追加ツールがいくつかあります。これにより、基本的に各アクションを分離し、要素間の相互作用とその動作状態を観察できるようになります。速度を変更して滑らかにすると、全体的な効果が向上します。
## JavaScript を使用した CSS アニメーション イベントのデバッグ
如果你不想去计算动画到底是什么时间什么地方出错了,你可以在事件触发时用一点点的javascript来调试,将其添加到 animationstart , animationiteration 和 animationend 事件上。
例如:
我经常看到有些人在keyframe的0%和100%中声明相同的属性值,这是完全没必要的而且会让代码变得很臃肿。浏览器将默认属性值作为初始值和结束值。
像这样子就是太肿了:
.element { animation: animation-name 2s linear infinite;} @keyframes animation-name { 0% { transform: translateX(200px); } 50% { transform: translateX(350px); } 100% { transform: translateX(200px); }}
正确的写法:
.element { transform: translateX(200px); animation: animation-name 2s linear infinite;} @keyframes animation-name { 50% { transform: translateX(350px); }}
创造简洁漂亮的动画通常意味着写一个具体的 cubic-bezier() 函数。调整Easing函数的工作类似于公司的调色板。你可以在运动中拥有属于自己个性的标志和“声音”。如果你想在整个网站中使用(为了保持统一,你应该这样做),最简单的方法是将一个或两个Easing函数存储在一个变量中,就像我们将颜料混合在调色板里。使用SASS或者其他的于处理器可以让其更简单:
//scss$smooth: cubic-bezier(0.17, 0.67, 0.48, 1.28); .foo { animation: animation-name 3s $smooth; } .bar { animation: animation-name 1s $smooth; }
当使用css的keyframe来做动画时我们希望尽可能用到GPU的性能,这就意味着如果你有多个动画你想更容易的DOM操作给接下来要加载的运动和懒加载的元素。你可以用CSS中的标准声明块让硬件加速原生的DOM(不是SVG)。复用元素的动画是有意义的,这里使用mixin:
@mixin accelerate($name) { will-change: $name; transform: translateZ(0); backface-visibility: hidden; perspective: 1000px;}.foo { @include accelerate(transform);}
当心,一次性转移太多元素可能会造成相反的效果并影响其性能。大多数动画应该正常,但是要如果你使用类似haml之类的标记语言来生成大量DOM元素时候要注意。
Smashing Magazine最近发表的一个工作之余的神奇项目, http://species-in-pieces.com/ 。在一个特定的部分,作者讨论了关于动画细节,其碎片导致的性能问题。他说:
假设你正在同时移动三十个物体,浏览器就要处理很多东西,然后或许就会有一些问题出现。如果你每个元素有0,199秒的速度和0.2秒的延迟,你可能会一次移动一个元素来修复这些问题。事实上,相同的运动并没必要重复产生。如果动画是一个链,性能是立即提高了30倍。
@for $i from 1 through $n { &:nth-child(#{$i}) { animation: loadIn 2s #{$i*0.11}s $easeOutSine forwards; }}
不仅如此,您可以使用它们来产生像颜色交错的视觉效果。(点击回放重新运行动画。)
当你在创建长动画时,我们通常将其排列成链式。类似:
animation: foo 3s ease-in-out, bar 4s 3s ease-in-out, brainz 6s 7s ease-in-out;
但是我们想想当你优化的时候,你发现你想改变动画的第二个属性值,这会影响接下来的它之后的所有元素,所以当我们调整之后。好像没什么大问题:
animation: foo 2.5s ease-in-out, bar 4s 2.5s ease-in-out, brainz 6s 6.5s ease-in-out;
现在让我们添加另一个动画也要再次进行调整(好的动画产生之前这种微调似乎是必然的),于是事情的效率好像就有点低了。当你这么做了3次,真的就非常低效率。
接着你可以想象一下如果你有两个动画并且要让他们保持一致…嗯你理解就好。这就是为什么每当当链式动画效果超越三个或四个,我就会使用JavaScript了。就个人而言,我比较喜欢 GreenSock animation API 因为它有非常强健的时间轴功能,但是很多JS允许你在不重新计算的情况下使用简单的堆栈动画创造工作流。
制作一个动画不仅仅是构建起来。通常情况下,它是人们通过编辑精炼和调试从而让一个项目从一个只是精心策划过的的运动变成一个有更好的性能的动画。希望这些建议能够成为你工具箱的工具,使你工作起来更加顺畅。