技術
「動きが速い」と感じたら、時間ではなく曲線を疑う
入場のアニメーションが忙しく見える。時間を伸ばしても変わらない。原因は時間ではなく曲線でした。 同じ勘違いを2回したので、両方を書いておきます。
1回目 —— 620ms かけているのに、9割が 205ms で終わっていた
使っていたのは、よく見かけるこの曲線です。
/* 前: 経過10%で49%、20%で75%、30%で88% まで進む */
cubic-bezier(0.16, 1, 0.3, 1)
/* 後: 経過30%で67%、9割まで 338ms */
cubic-bezier(0.22, 0.61, 0.36, 1)前の曲線は動きの大半を頭で済ませてしまいます。経過10%の時点で49%、20%で75%、30%で88%。つまり 620ms の入場でも、9割は 205ms で終わっているということです。
時間の指定はゆったりしているのに、サイト全体が忙しく見える。時間だけ伸ばしても体感は変わりませんでした。 曲線を変えて初めて落ち着きました。
2回目 —— 字送りが 22ms で、全部ほぼ同時に動いていた
見出しを1文字ずつ現す演出でも同じことをしました。1字が動く長さは 420ms、字と字の間隔は 22ms。12字の見出しなら、送りの幅は 242ms しかありません。
1字が 420ms かけて動くのに、送りが 242ms。全12字がほぼ同時に animating している状態です。波として読めないまま、見出しがまとめて着地していました。
間隔を 36ms にして、送りの幅(字数−1 × 間隔)を 1字の長さとだいたい同じにしました。波が見えて、それでいて見出しは1つの動作として着地します。
片方だけ動かすと壊れます。 送りだけ伸ばすとバラバラに見え、1字だけ伸ばすとまた同時に見えます。
役割でイージングを2つに分ける
いまは2種類だけ持っています。混ぜません。
--ease-out 現れるもの(入場・スクロール連動)
--ease-spring 操作の反応(押した・切り替えた)入場が跳ねると落ち着きが無くなり、操作が跳ねないと反応が鈍く感じます。以前は1種類を全部に使っていました。
バネのほうは linear() で作った擬似的なものです。JS のバネ実装は入れていません。未対応の環境では素直な曲線に落ちるので、動かなくなるのではなく跳ねなくなるだけです。
そもそも入場を JS に持たせない
前提として、入場は CSS で書いています。アニメーションのライブラリで入場を書くと、サーバーで描かれた HTML が opacity: 0 のまま出ます。JS が動くまで、見出しが読めない状態になります。
渡すのは順番だけ(何文字目か、何番目のマスか)で、遅延の計算は CSS の側が持ちます。遅延の値を2箇所に持たないことも、ここで一度失敗して決めました —— 同じ 22ms が2箇所にあり、片方だけ直したせいで、見出しが組み終わる前に次の要素が動き始めていました。