ベジエ曲線の描画
に公開(に更新)履歴 (4)
別の記事でアニメーションをつけるのにベジエ曲線が必要だったので、つくりがてら記事にすることにしました。
ベジエ曲線はいくつかの制御点から得られる曲線で、制御点の数によって3つなら2次ベジエ曲線、4つなら3次ベジエ曲線などと呼ばれます。私がほしかったのは3次なのでこれ以降は3次限定です。
## 3次ベジエ曲線
3次ベジエ曲線は4つの制御点からなります。それぞれ位置を B0,B1,B2,B3 とすると曲線上の点 P(t) は次式で表されます。
ただし 0≤t≤1 です。P(0) は B0 で P(1) は B3 になります。
(t: number) => [number, number]
を返す getCubicBezierFunction
は次のように書けます。
次のサンプルは上記の関数を使っており、 t に対応する (x,y) を確認できます。
これで (B0,B1,B2,B3,t) から (x,y) が求められるようになりましたが、私がほしかったのは
CSS の cubic-bezier(0.42,0,0.58,1)
のように使えるもので、以下のようにアニメーションの進み方を指定するものです。
x が時間で、曲線との交点の y 座標がアニメーションの進捗になっています。つまり、ほしいのは (B0,B1,B2,B3,x) から y を求める関数です。
B0=(0,0) と B3=(1,1) は固定なので、(x(t),y(t)) は次のようになります。
これをy について解こうとすると x が一意に定まらないケースがあって困ります。仕方がないので
N 個の t で (x,y) を求めておいて、内分点で近似することにしました。
ちょうどいい N はいくつなのかという問題ですが、N=20で良さそうでした。N=10
だと両端の動きにぎこちなさがありますが、アニメーションの周期 T が小さければ気にならないですね。以下では
N と T を変更できるようにしているので試してみてください。
<easing-function>
の ease, ease-in, ease-out, ease-in-out は次のように書けます。
以上です。