2016-03-25 18 views
2

ズームアニメーションをループするとき、線形タイミングは線形には感じられませんが、開始時にはむしろ遅く、最後には高速になります。線形ズームのベジェ曲線を計算する

正しいカーブを計算する方法を教えてください。 コメントが必要な場合は、さらに詳しい情報が必要です。

私は明らかに論理を理解するにはあまりにも愚かなので、このペンでは、私は手を描いた曲線を使用して問題を解決しようとしています。

http://codepen.io/pixelass/pen/qZjBQy

// mathematically correct curve ? 
@function linear-zoom() { 
    // add your code here 
    $sx: 0; 
    $sy: 0; 
    $ex: 1; 
    $ey: 1; 
    $curve: ($sx, $sy, $ex, $ey); 
    @return $curve; 
} 

zoom hack

+0

パラメータを手で調整して見栄えがよくないのは何ですか?それは、文字通り、 "正しいと感じる"ものを得るための唯一の方法です - 数学は、一般的な経験でどの人間が "最もスムーズに見える"ように伝えることができません(実際には、A/Bはこれをテストする) –

+0

@ Mike'Pomax'Kamermans私は主にその背後にある論理に興味があると思う。 – pixelass

+0

http://cubic-bezier.comと表示されていますか?または、ロジックの*ロット*が必要な場合は、https://pomax.github.io/bezierinfo? –

答えて

3

使用しているスケールのパラメータは2の倍数、線形ので、あなたが線形アニメーションを使用速度がスケーリング増加するが、対数距離増加しています。

いくつかの数字を見てみましょう。まず、我々は0.5から2に拡張サークルので、2つのlog2段階:

t=0 => scale(0.5) 
t=0.25 => scale((0.75 * 0.5 + 0.25 * 2)) = scale(0.875) 
t=0.5 => scale((0.5 * 0.5 + 0.5 * 2)) = scale(1.25) 
t=0.75 => scale((0.25 * 0.5 + 0.75 * 2)) = scale(1.625) 
t=1 => scale(2) 

は、だから、開始と終了の間に素晴らしい、線形トランジションを探します。同じことをするためにサークルを追加することができると考えられるかもしれませんが、そうすると対数的な振る舞いになります。理由を見てみましょう:0.25の尺度を1に追加しましょう。すべての時間間隔で、大きな円の半径が二回小さな円である...しかし、それはまた、小さい円上の点を意味するので、それは、あなたが望むものないです:良いと思われること

t=0 => scale(0.25) 
t=0.25 => scale((0.75 * 0.25 + 0.25)) = scale(0.4375) 
t=0.5 => scale((0.5 * 0.25 + 0.5)) = scale(0.625) 
t=0.75 => scale((0.25 * 0.25 + 0.75)) = scale(0.8125) 
t=1 => scale(1) 

大きな円の一点をその距離の2倍(1.5単位)移動させる時に0.75単位しか動かさない。円が大きくなるにつれて、単純な2^tの式に従って、画面全体を移動する速度が速くなることがわかります。

これに対処するには、とは無関係に、特定の対数増殖を補正する必要があります。異なるパラメータのためにそれぞれアニメーションがあります。すべてのカーブでベジエ曲線を得ることは数学的に不可能ですが、人間は完璧な数学のマシンではないので、あなたのコードブックのような小さな画面でそれを取り除くことができます。 /パラメータの最後のセットab1/(2^t)の間の関数1/(2^t)を近似するベジェ曲線を設定する必要があります。これはあまり面白くないので、ベジェ曲線で特定の間隔でseries for 1/2^x up to order 2を近似する必要があります。キュービックイージングパラメータとして私たちに与える座標。

これには2つの方法があります。関数を最も小さい値から最大値に最適化する1つのベジェ曲線を見つけて、曲線分割を使って各部分区間のパラメータを見つけるか、別の間隔。最初は(わずかに)より簡単ですが、低次系列近似のために1/2^xの2番目の方が良いですが、非常に多くの作業がありますので、これを行う方法を知りたい場合はmath.stackexchange.comが入手するのが良い場所です真の数学的な底にここに。

ほとんどのプログラマーが作業できる「Stackoverflowの答え」は、「いくつかの間隔でいくつかのカーブ」のルックアップテーブルを作成し、それらの間の補間を使用して、間隔の間のどこかにある間隔に対処しますあなたはLUTを構築するために使用しました:あなたは周りに横たわっている言語で間隔をプロットし、そのプロットを重ねてcubic-bezier.comのようなものを使用し、コントロールポイントを視認することによってこれらのプロットのそれぞれに「良い適合」を単に見つけるだけです。あなたが使っている間隔の10分の間、それを行います。あなたは行くのが良いです。

これは確かに少ない数学で、あなたが「プログラム」の一般的な解決策として、その解決策ではないことができますが、それ効率的である:ユーザー知覚の観点から、このソリューションは、すでに十分以上にする必要があります滑らかに感じる。

+1

または単に繰り返し)0.97を繰り返します。 –

+1

@ArifBurhan正しい間に各ベジエフィットを見つけるのに便利ではありませんが、あなたはまだ*その*関数に近づかなければならないので(CSSは、私が本当に理解できない理由のためにカスタムイージング関数あなたが必要とするのは、 '(t、a、b)=> 1 /(2^lerp(t、a、b))'番号ジェネレータ) –

+0

個々のlerpsはまともなベジエを思いつくことができますが、特定の間隔を近似するために必要なコントロールポイントのプロットを行うことができます(2つの線を渡す必要があります)。次に、関数を簡単に表現できるかどうかを確認します間隔の開始値の点でそれらのために。もしそうなら、それは正しいパラメータを常に得るための非常に堅実な方法です。 –