FigmaのカスタムスプリングをGSAPで再現するためのイージング関数

  • URLをコピーしました!
目次

FigmaのイージングにはCSSでできるものと、JavaScriptが必要なものがある

FigmaのPrototypeで、Smart animateを選択したときに選べるイージングには、CSSで表現できるイージング(ベジエ)と、JavaScriptが必要なイージング(スプリング)の2つに分かれています。

  • CSSのイージング関数(cubic-bazier)にできる:ベジエ
    • Ease in (ease-in )
    • Ease out(ease-out
    • Ease in and out(ease-in-out
    • Ease in back(cubic-bezier(0.3, -0.05, 0.7, -0.5)
    • Ease out back(cubic-bezier(0.45, 1.45, 0.8, 1)
    • Ease in and out back(cubic-bezier(0.7, -0.4, 0.4, 1.4)
    • Custom bezier
  • JavaScriptが必要:スプリング
    • Gentle
    • Quick
    • Bouncy
    • Slow
    • Custom spring
スクリーンショット:FigmaのSmart animateのイージング選択画面

スプリングの場合「Stiffness」「Damping」「Mass」の数値の組み合わせで、バネの性質を表現して、どれくらい強く弾むか、どれくらい早く弾むのが止まるかなどを調整します。

が、利用するアニメーションライブラリごとにこの設定値を使えたり使えなかったり、使い方が違ったりします。

GSAPには「Stiffness」「Damping」「Mass」のパラメーター指定がない

筆者はJavaScriptが必要なアニメーション表現にはGSAPを用いることが多いのですが、
GSAPのイージングには「Stiffness」「Damping」「Mass」のパラメーターを指定する方法がありません。

※GSAPの有料機能のCustomBounceについての詳細は未確認ですが、パラメーターが異なるようです。

また、GSAPと同じようなアニメーションライブラリanime.jsでは「Stiffness」「Damping」「Mass」を指定する方法があることが分かりました。

GSAP用のイージング関数を自作する

anime.jsのスプリング関数を確認すると、webkitのspring.jsを参考にしていることが分かりました。
そこで、Figmaのスプリングもwebkitのspring.jsと同様の計算であると予想しました。

※ただし、筆者の物理の知識は無いに等しいため、この記事で大規模言語モデル(LLM)のWebサービスClaudeに「anime.jsのスプリング関数及びwebkitのspring.jsを参考にしたGSAP用のイージング関数」を書いてもらい、それを調整したものを示します。

イージング関数

Figmaの指定が「Stiffness」「Damping」「Mass」の順番なので、引数もその順番に合わせてあります。
また、Figmaからvelocityが出てこないのでvelocityは0にしておきます。

// カスタムspringイージング関数
// Spring solver inspired by Webkit Copyright © 2016 Apple Inc. All rights reserved. https://webkit.org/demos/spring/spring.js
function customSpring(stiffness, damping, mass, velocity = 0) {
    return function (t) {

        // 減衰比(ζ)を計算
        const zeta = damping / (2 * Math.sqrt(stiffness * mass));

        // 自然角振動数(ω)を計算
        const omega = Math.sqrt(stiffness / mass);

        // 初期変位を計算
        const initialDisplacement = velocity / omega;

        // 減衰比が1未満の場合(減衰振動)
        if (zeta < 1) {
            // 減衰角振動数(ωd)を計算
            const omega_d = omega * Math.sqrt(1 - zeta * zeta);

            // 減衰振動の方程式を使用して変位を計算
            return 1 - (Math.exp(-zeta * omega * t) *
                (initialDisplacement * omega * Math.sin(omega_d * t) / omega_d +
                    Math.cos(omega_d * t)));
        } else {
            // 減衰比が1以上の場合(過減衰)
            // 過減衰の方程式を使用して変位を計算
            const alpha = omega * Math.sqrt(zeta * zeta - 1);
            return 1 - (Math.exp(-zeta * omega * t) *
                (initialDisplacement * omega * Math.sinh(alpha * t) / alpha +
                    Math.cosh(alpha * t)));
        }
    };
}

使い方

GSAPのTweenのeaseとして、customSpring(Stiffness,Damping,Mass) を渡します。

gsap.to(".box", {
    x: 300,
    duration: 0.8,
    ease: customSpring(100, 15, 1)
});

Figmaのプロトタイプと動作が一致するかの確認

FigmaのプロトタイプをGIF画像として書き出したものと、GSAPで実装したものを並べて配置することで、今回作成したイージング関数とFigmaのプロトタイプの動作が一致するかを目視で確認します。

※プロトタイプをGIFで書き足すためにExport to GIF/Videoを利用しました。

デモ

目視確認のため、主観にはなりますが動作は作成したデモの範囲では動作は一致しているように見えます。

ブラウザ上で様々な設定値の動作を、簡易的に確認できるようにする

デモ(Test Tool)

Figmaの設定と、GSAPで今回のイージング関数を使った場合の動作との間に差異がないか、検証するために毎回JavaScriptを書くのは面倒な気がします。

そこで、「Duration」「Stiffness」「Damping」「Mass」の4つの値を入力して「Run」ボタンを押すだけで動作が確認できるテストツールもつくりました。

スクリーンショット:Duration, Stiffness, Damping, Mass の入力と、Runのボタン

まとめ

  • Figmaで設定できるイージングには、CSSで実現できるもの(ベジエ)とJavaScriptが必要なもの(スプリング)がある
  • Figmaから出力できるスプリングの設定値は、そのままではGSAPでは利用できない
  • Figmaの設定値をもとにGSAPで使えるイージング関数を作成すれば、実装自体は可能
    • ただしFigmaの設定値からどのような物理計算をするかの詳細は不明
    • webkitのspring.jsの計算で同様のみためになりそうだが、目視の確認は必要そう!
よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

目次