2

現在のスクロール位置に基づいて値をアニメーション化する単純な関数を作成しました。

function scrollTransition(startValue, endValue, initScroll, distance, scrollTop) {
    var
        min = Math.min,
        max = Math.max,
        sum;

    if(startValue > endValue) {
        sum = min(max((endValue - startValue) / distance * (scrollTop - initScroll) + startValue, endValue), startValue);
    } else {
        sum = min(max((endValue - startValue) / distance * (scrollTop - initScroll) + startValue, startValue), endValue);
    }

    return sum;
}

必要なのは、開始値と終了値、遷移が開始するときの初期スクロール位置、および距離 (px) を設定することだけです。したがって、「initScroll」が 500 で距離が 200 の場合、トランジションは 700px (scrollTop) で終了します。「問題」は、それが単なる線形アニメーションであることです。私がやろうとしているのは、jQuery .animation() 関数で行うように、関数に 5 番目のパラメーター (「イージング」) を追加することです。

これらは私が話しているイージング関数です ( https://github.com/danro/jquery-easing/blob/master/jquery.easing.js ) が、この関数にそれらを追加する方法がわからないので、私は次のようなものを使用できます

// in window scroll function
$el.css({
     "margin-top" : scrollTransition(-300, 500, 500, 1000, "easeOutBack")
});

このようなことはまったく可能ですか、それとも線形遷移に固執する必要がありますか?

あなたの助けと時間を前もってありがとう。

4

1 に答える 1

10

アップデート:

そうですね、時間はかかりましたが、納得できたと思います。独自の「カスタム」関数を作成したため、達成するのが少し難しくなりました。

直感

私が行ったことをすべて説明するために、線形公式の絶対基底から始めましょう。

  • カスタム関数を線形関数として視覚化できるとしましょうf(x)=x
  • イージング関数を非線形関数として視覚化できるとしましょう。たとえば、関数g(x)=sin(x)をイージング関数と見なすとします (これはイージング メソッドに対応しますeaseInSine) 。

これらの関数を 2 次元プロットで考えてみましょう。

線形および非線形関数のプロット

ご覧のとおり、2 つの異なる関数を描画しました。これらの関数を JavaScript の関数として視覚化すると、これらは独立して呼び出すことができる 2 つの別個の関数になります。例えば:

function linear(x)
{
   return x;
}

function sin(x)
{
   return Math.sin(x);
}

これで、両方の関数を scrollTransition として使用できますが、それは私たちが望んでいるものではありません。

特定の質問をしました:非線形関数をカスタム線形関数に追加するにはどうすればよいですか?

それでは、2 つの関数の可能性をいくつか考えてみましょう。

  1. それらを一緒に追加できます
  2. それらを差し引くことができます
  3. 私たちは何もできません
  4. 平均を取ることができます
  5. 等...

最初の点を視覚化しましょう:

ここに画像の説明を入力

灰色の線は元の機能を示し、青い線は追加された機能を示しています。

2 番目の点については、次のようになります。

ここに画像の説明を入力

ここでも、灰色の線は元の機能を示し、青い線は一緒に追加された機能を示しています。(まあ...この場合:「互いに減算」)

コード

私たちが知っているすべてを考えてみましょう:

  • あなたの関数が特定の線形決定値を返すことはわかっています
  • イージング関数は特定の非線形決定値を返すことがわかっています

グラフと同じように、これらの値を足したり引いたりして関数を足し合わせることができます。

関数でこれを実現するために、関数に 2 つのパラメーターを追加しました。

  • easingEffectこれは、カスタム関数に追加 (または削除) する非線形イージング効果の名前である必要があります
  • plus-1これは値を取ることができ、非線形効果が どのよう0に処理されるか1を決定します。
    • -1非線形関数はカスタム線形関数から差し引かれます
    • 0 非線形関数は使用されません
    • 1 非線形関数がカスタム線形関数に追加されます

この例は次のようになります。

$(".element").css({
    "opacity": 1-scrollTransition(0, 1, 0, 400, scrollTop, "easeInSine", 1),
    "left": scrollTransition(0, 200, 0, 300, scrollTop, "easeOutBounce", 1)
});

次に、関数内で私が行ったことは、基本的に次のようになります。

sum += plus*easingEffect(null, scrollTop, startValue, endValue, distance);

イージング効果は、自分で提供したイージング jsによって決定されます。

残念ながら、カスタム関数の場合、関数を呼び出さに値を返すイージング関数が必要なため、多くの手作業を行うことになりましたjQuery.animate()。しかし、もう心配する必要はありません。すべての作業は既に完了しているので、座って設定をいじって、何が起こるかを確認してください。

ここで (完全に実装可能な) ソリューションを見つけることができます: jsFiddle のコード

このようないくつかのクールなことを行うことができます。

実装の詳細

次のことに注意してください。

の場合opacity、2 つの値を一緒に追加することは非常に危険です。なぜなら、より大きな引数を渡そうとすると、CSS プロパティがエラーを出すからです1。したがって、私は次のことを行います。

 "opacity": 1-scrollTransition(0, 1, 0, 400, scrollTop, "easeInSine", 1),

したがって、基本的に関数を逆にして (関数を 1 から 0 ではなく 0 から 1 に「機能」させる) 1-'the function'、値が 1 を超えないようにします。非線形関数。

また、JavaScript を下にスクロールすると、すべての関数と巨大な switch ステートメントが表示されます。これらすべてを最終的な JavaScript ファイルに追加する必要があります。

したがって、JavaScript セクション全体を自分のプロジェクトにコピーすることをお勧めします。

さらに、jsFiddle は一目瞭然です。

頑張ってください。あなたの質問に答えていただければ幸いです。

更新 2

demrks次のことを行いました:

sum = easeOutBounce(null, sum, startValue, endValue, distance);

パラメータをイージング関数に追加する方法をより直感sum的に理解するには、次のグラフを検討してください。

ここに画像の説明を入力

青い線が関数の結果を示す場所。

つまり、基本的に行っていることはlinear transformation、イージング関数またはイージング関数と呼ばれlinear mappingます。詳細については、こちらをご覧ください。

しかし、基本的には、次のプロパティによってイージング関数の「フォーム」を変更しているということです。

  • イージング アニメーションの「進行」速度
  • 開始時/終了時

それがあなたが達成したいことであれば、まったく問題なく、jsFiddleの外でも使用できます。ただし、パラメーターに余分なレベルの複雑さを追加したため、全体の正確なアニメーション (ジョイント関数) を制御できなくなるため、少し面倒に思えます。つまり、結果がどうなるか正確にわからないため、プログラミングが難しくなります。

それがあなたの最後の関心点にも答えてくれることを願っています:)

ハッピープログラミング!

更新 3

demrksイージング関数のパラメーターに制限がある理由を尋ねました。

easingそのような関数を考えてみましょう:

function easeOutBounce(x, t, b, c, d) {
    if ((t/=d) < (1/2.75)) {
        return c*(7.5625*t*t) + b;
    } else if (t < (2/2.75)) {
        return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if (t < (2.5/2.75)) {
        return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
}

//x = null;
//t = currentTime;
//b = begin;
//c = end;
//d = distance;

関数を見るだけで、次の結論に達します。

  • の場合c=0、関数は値を返しますb
    • b<0との場合c=0、関数は負の値を返します。b
  • の場合c<0、関数は負の値を返します

不透明度を次のように定義したことに注意してください。

"opacity": 1-scrollTransition(0, 1, 0, 400, scrollTop, "easeInSine", 1)

したがって、関数scrollTransition(0, 1, 0, 400, scrollTop, "easeInSine", 1)が負の値を返す場合、$(".element").css(...);プロパティにエラーが発生するため、何も起こりません。

したがって、基本的にイージング関数は正常に機能します。プロパティ opacity にそれらを適用すると、制約が発生することがあります。

  • endValue > 0

関数の振る舞いについて話したら、別の関数を考えてみましょう:

 function easeInOutElastic(x, t, b, c, d) {
    var s=1.70158;var p=0;var a=c;
    if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
}

dこの場合、関数は変数(距離)に大きく依存することに注意してください。

したがって、数式は正常に機能します。

それらを適用する方法と物事を複雑にする可能性のある動作に注意する必要があるだけです.

jsFiddle の何が問題なのか

jsFiddle での作業に関しては、ドキュメントの初期化方法に十分注意してください。

たとえば、アニメーション スペース(アニメーションを適切に実行するために必要なスペース)よりも大きなスペースを配置した場合イージング-300を使用したアニメーション化が正常に機能することがわかりました。200document width

ここ-300からアニメーション化する作業コードを見ることができます。200

ドキュメントの幅を変更したことに注意してください。

body {
    height: 2000px;
    width: 800px;
}

それはあなたの質問に答えるはずです。幸運を!

更新 4

を短縮するswitch statementには、次も使用できます。

var call = eval(easingEffect);
sum += call(null, scrollTop, startValue, endValue, distance);

この例でわかるように。これにより、手作業を節約できる可能性があります。

于 2013-07-04T15:31:44.493 に答える