アニメーションをスムーズに見せるためのテクニック「指数平滑法」とはどんなものなのか?

アニメーションをスムーズに見せるためのテクニック「指数平滑法」とはどんなものなのか? - 画像


グラフィック系の開発者であるニキータ・リシッツァ氏が、「自身のプロダクトのあらゆる場所で使用している」と述べるお気に入りのテクニックである「指数平滑法」について解説を投稿しました。
My favourite animation trick: exponential smoothing | lisyarus blog
https://lisyarus.github.io/blog/programming/2023/02/21/exponential-smoothing.html
リシッツァ氏は下図のようなトグルボタンを例に解説を行っています。クリックすると「オン」「オフ」が切り替わります。まだアニメーションを何も設置しておらず、トグルボタンは左端と右端を瞬間移動しています。

機能的にはアニメーションが設定されていなくとも問題はないのですが、アニメーションを設定することでユーザーは何が起こっているのかを理解しやすくなります。一定速度でボタンが動くようなアニメーションを設定すると下図のようになります。

アニメーションの速度が一定だとややぎこちなく見えるため、速度を「3t^2-2t^3」という古典的なベジェ曲線に変えてみると下図のようになります。

また、平方根を使用した「sqrt(t)」に変えてみると下図の通り。

上記の3つの違いは分かりにくいものの、スローにすると下図のようにはっきり違いが現れます。

このうち、リシッツァ氏は「動き始めは大きく動き、目的地に近づくにつれてスピードが落ちる」ため平方根を使用したアニメーションが一番好きとのこと。しかし、平方根を使用すると「オフ→オン」にする際のアニメーションは「sqrt(t)」で良いものの、「オン→オフ」にする反対側のアニメーションで同様の動きを実現するには「1-sqrt(1-t)」という数式を使用する必要があり、アニメーションの途中でオンオフを切り替えるとボタンがワープしてしまうという問題が発生してしまいます。

平方根を使用したアニメーションの利点を生かしつつ、可能な限りワープが発生しないようにリシッツァ氏が開発したアニメーションの数式が「position.x += (target - position.x)*(1-exp(-dt*speed))」です。リシッツァ氏はこの数式を利用したアニメーションを指数平滑法と名付けました。

平方根との比較は下図の通り。途中でオンオフを切り替えてもほとんどボタンがワープしないことが分かります。

指数平滑法での位置の変化量である「(1-exp(-dt*speed))」は一見奇妙に見えるものの、実は現在位置をx、目標位置をa、スピードをcと置いて下記で表される微分方程式を解いた結果導出される数式とのこと。元のブログでは具体的な計算が行われているため、気になる人は確認してみてください。

アニメーションをスムーズに見せるためのテクニック「指数平滑法」とはどんなものなのか? - 画像

ジャンルで探す