copy_people copy_things copy_matter copy_heart copy_txt ttl_topics ico_blank ico_facebook ico_twitter ico_hatebu ico_index

2019/04/05

SASSで3次ベジェ曲線の関数を作ってみた

Written by Yusuke Sugano

  • SASS

INDEX

    こんにちは!エンジニアのsuganoです。

    アニメーションの表現の幅を広げたい!という目的と
    ふと曲線的なアニメーションを作りたいと思い
    今回はベジェ曲線を使ったアニメーションについて調べてみました。
    ベジェ曲線に関する記事を色々調べてみたところ
    そのまま使うのは難しそうだったので、自分なりに分かりやすい関数を作ってみたいと思います。

    ベジェ曲線について

    ベジェ曲線は「2次曲線」と「3次曲線」というものが2つあります。
    ➔ 2次は普通の曲線で、3次はS型曲線をイメージしたもの。

    2次曲線は3点(始点/制御点/終点)、3次曲線は4点(始点/制御点×2/終点)が必要です。
    詳しくはこの記事に書いてあるので、ぜひご参考下さい。
    ベジェ曲線について

    3次ベジェ曲線は、イージングのグラフでお馴染みかと思います。
    今回は、この3次ベジェ曲線をイージングのタイミング調整ではなく、アニメーションとして扱っていきます。
    イージングで設定する時に使うのが、cubin-bezierの記法です。
    cubic-bezierを使った3次ベジェ曲線は、
    こちらのジェネレーターを使うとイメージしやすいと思います。

    始点と終点は大体固定値で、
    調整するところは制御点の位置だけということを
    踏まえた上で関数を作成してみたいと思います。

    公式

    まずは、3次ベジェ曲線の公式です。
    関数を作る時は、公式が必要なので調べてみました。
    ※公式は覚えなくて良いです。

    【3次ベジェ曲線の公式】
    x=(1-t)³x1 + 3(1-t)²tx2 + 3(1-t)t²x3 + t³x4
    y=(1-t)³y1 + 3(1-t)²ty2 + 3(1-t)t²y3 + t³y4

    ※Wikipediaにも公式があるので、ご参考まで。
    https://en.wikipedia.org/wiki/B%C3%A9zier_curve

    これ、大学の時に習った幾何学で見たことあるような…
    まさかここで役に立つとは…!!(笑)
    まぁそれは置いといて、公式をもとにSassで関数を作ってみました。

    X軸とY軸のそれぞれの関数を用意する

    【X軸】 x=(1-t)³x1 + 3(1-t)²tx2 + 3(1-t)t²x3 + t³x4

    @function getPointX($t, $x1, $x2, $x3, $x4) {
     $tp: 1 - $t;
    
     $x: $tp * $tp * $tp * $x1 + 3 * $tp * $tp * $t * $x2 + 3 * $tp * $t * $t * $x3 + $t * $t * $t * $x4;
    
     @return $x + px;
    }
    

    【Y軸】 y=(1-t)³y1 + 3(1-t)²ty2 + 3(1-t)t²y3 + t³y4

    @function getPointY($t, $y1, $y2, $y3, $y4) {
     $tp: 1 - $t;
    
     $y: $tp * $tp * $tp * $y1 + 3 * $tp * $tp * $t * $y2 + 3 * $tp * $t * $t * $y3 + $t * $t * $t * $y4;
    
     @return $y + px;
    }
    

    X軸とY軸のそれぞれの関数が完成しました。

    @keyframesを作る

    次は、animationで実現できる形にする必要があります。
    @for文については、値をtranslateに置き換えられるような式になっています。

    @keyframes object {
     $startX: ; // 開始位置X
     $startY: ; // 開始位置Y
     $p1X: ; // 制御点X1
     $p1Y: ; // 制御点Y1
     $p2X: ; // 制御点X2
     $p2Y: ; // 制御点Y2
     $endX: ; // 終了位置X
     $endY: ; // 終了位置Y
    
     @for $i from 0 through 100 {
      #{$i}% {
       transform: translate(getPointX($i * 0.01, $startX, $p1X, $p2X, $endX), getPointY($i * 0.01, $startY, $p1Y, $p2Y, $endY));
      }
     }
    }
    

    このように、
    始点(start)/終点(end)/制御点(p1,p2)のXY座標を与えて
    tを0から1へ徐々に変化させると曲線になります。

    ここまで書けたら、早速実装してみましょう。

    3次ベジェ曲線を使った、イージング曲線移動

    それでは、先程のジェネレーターを使って
    曲線のパスに沿ったアニメーションをしてみたいと思います。

    まず、XY軸の範囲が100pxだとします。
    始点(X,Y)は(0,-100)なので、absoluteの指定で「top: 100px; left: 0;」を書きます。
    そして、この基準から【開始位置、制御点、終了位置】のそれぞれの数値を入力していきます。
    開始位置は(0,0)、終了位置は始点の基準から見ると(-100,-100)を指しています。
    ========================
    ① 制御点の調整位置
    ➔ cubic-bezier($p1X, -$p1Y, $p2X, -$p2Y)

    ② ●のカラーは以下の内容だと考えて下さい。
    ➔ 白:開始位置/終了位置
    ➔ ピンク:制御点1
    ➔ 青:制御点2

    ========================

    ※制御点のタイミングを調整したいときは
    cubic-bezier($p1X, -$p1Y, $p2X, -$p2Y)のXY座標を入力していきます。
    ここでは、XY軸の範囲が100pxなので
    XY座標の値に100を掛けて、数字入力していくと
    イージング曲線のパスに沿ったアニメーションが出来ます。

    いくつか例を書いてみたので、良かったら参考にしてみて下さい。

    ① cubic-bezier(0,1,1,0)
    http://cubic-bezier.com/#0,1,1,0

    ② cubic-bezier(1,0,0,1)
    http://cubic-bezier.com/#1,0,0,1

    ③ cubic-bezier(0,.35,1,.65)
    http://cubic-bezier.com/#0,.35,1,.65

    最後に

    実際にベジェ曲線を使ったアニメーションで、サイトに取り入れるものがあるかどうかは分からないですが
    こういう動きもできますよーということを知って頂ければ幸いです。
    このように自分なりにsassの関数を作ってみると、様々なアニメーションが作れると思います。
    ではでは〜!!

    CONTACT

    お仕事のご相談や、弊社についてのご質問や
    ご要望など、お気軽にお問い合わせください。

    View