2

setInterval または RequestAnimationFrame を使用して、X と Y の間の lerping から進行値を取得したいと思います。X が 0 で Y が 1 であると仮定すると、開始時に 0、半分に 0.5、終了時に 1 が必要です。

これが特定の時間枠で発生することを望みます。たとえば、5 秒とします。setInterval/RequestAnimationFrame が 2.5 秒に達すると、半分の値 0.5 が発生することを意味します。

最後に、pingPong にしたいので、5 秒に達すると、0.9、0.8、0.7 などのように値が減少し、増加せず、0、0.1、0.2 から再び開始します...

これまでの私のコードは次のとおりです。

/*
function lerp(start, end, time) {
    return start * (1.0 - time) + end * time;
}
*/
function lerp (start, end, amt){
  return (1-amt)*start+amt*end;
}

function repeat(t, len) {
  console.log('t: ' + t + ', len: ' + len);
    return t - Math.floor(t / len) * len;
}

function pingPong(t, len) {
    t = repeat(t, len * 2);
    return len - Math.abs(t-len);
}

var transitionDuration = 1;
var startTime = Date.now()/1000;
var startPos = 0;
var endPos = 1;

setInterval(function () {
    var currentTime = Date.now()/1000;
  console.log('currentTime:', currentTime);
    var adjustedTime = pingPong(currentTime-startTime, transitionDuration);
    var x = lerp(startPos, endPos, adjustedTime);

    console.log(Math.abs(x.toFixed(2)));

}, 100);

これどうやってするの?

4

2 に答える 2

5

線形補間の基本式は次のようになります

InterpolatedValue = X*t + Y*(1-t)

ここでX、 とYは と の間で補間される値で、 とtの間のパラメータで、補間の程度を決定します0。利回りと利回り。さらに、周期の長さが の周期的な動きが必要で、補間の方向が交互になります。これは次のようにして実現できます。が時間とともに増加する非負の数である場合、計算します。10X1Y5t

t' = t - t / 10

発生した以前の期間をすべて削除し、

t'' = t'     : t' in [0,5)
      5 - t' : t' in [5,10)

その後設定

t''' = t' / 5

パラメータを正規化し[0,1]、最初から基本的な補間式を使用します。

線形補間やその他のさまざまな方法がここに集められていることに注意してください。

于 2015-11-25T12:23:03.120 に答える
1

あなたの説明から、特定のフレームには6つの状態があります。

  1. 現在のlerpの開始時間
  2. Lerpタイムスパン
  3. 現在の方向
  4. 現在の時刻
  5. 開始値
  6. 終了値

これらから、必要な進捗値を計算できます。たとえば、次のようにします。

function progressValue(startTime, lerpSpanSeconds, dir, 
                       currentTime X, Y, dir, currentTime) {
    // lerp
    return 0.42;
}

requestAnimationFrame の場合、渡す単純なコールバックが必要です。つまり、関数は、実行時に取得できるものを除いて、必要なものをすべて認識している必要があります。ここでは、実行時に現在の時刻を取得し、そこから残りの作業を行う必要があります。

function animableThing() {
    var startTime = 7;
    var lerpSpanSeconds = 3;
    var dir = +1;
    var X = 0;
    var Y = 1;
    var currentTime = GetCurrentUnicornTime();
    var thingToAnimate = document.getElementById('myAnimableElement');

    var progress = progressValue(startTime, lerpSpanSeconds, dir, 
          currentTime, X, Y, dir, currentTime);
    // reverse when we hit the end
    if(progress > Y) {
        dir *= -1;
        startTime = currentTime;
        progress = Y;
    }

    DrawAnimationThing(thingToAnimate, progress);

    // continue the animation
    window.requestAnimationFrame(animableThing);
}

しかし、問題があります。スクリプトからの値または画面からの入力、または画面上の要素に関する最新情報を使用してアニメーションを設定できるようにしたい場合はanimableThing、新しい価値。見よ、母親:

function MotherOfAnimableThings(startTime, lerpSpanSeconds, dir, X, Y, 
   thingToAnimate)
{
    // Passed in variables have scope outside the animableThing, these
    // will be private to the animableThing function.
    // Consider defaulting or validation here

    // Construct a new function freshly each time the Mother is called,
    // and return it to the caller. Note that we assign a variable here
    // so that we can re-call RequestAnimationFrame to continue the loop
    var callback = (function() {
        var currentTime = GetCurrentUnicornTime();
        var progress = progressValue(startTime, lerpSpanSeconds, dir, 
              currentTime, X, Y, dir, currentTime);
        // reverse when we hit the end
        if(progress > Y) {
            dir *= -1;
            startTime = currentTime;
            progress = Y;
        }

        DrawAnimationThing(thingToAnimate, progress);

        window.requestAnimationFrame(callback);
    });
    return callback;
}

さらに進んで、呼び出し元が呼び出す progressValue 関数、または実際にはコールバックを渡すことで、これを他のタイプのものに一般的にすることができます。これにより、任意の要素、Draw 関数、セットアップ関数を取得してアニメーション化しますが、これは妥当な出発点です。

上記では、Mother を呼び出してanimableThing関数を作成し、それを使用して RequestAnimationFrame を呼び出すだけです。それ以降は、RequestAnimationFrame を内部的に呼び出してサイクルを継続します。

これで、停止させたいので、チェックできるコールバックに変数を追加して、できるようにします

var animableThing = MotherOfAnimableThings(...);
window.requestAnimationFrame(animableThing);
// ... later
animableThing.stop = true; // it should stop on the next frame
于 2015-11-25T12:44:04.097 に答える