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

Blog

こんにちは!エンジニアの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の関数を作ってみると、様々なアニメーションが作れると思います。
ではでは〜!!