2015-11-25 21 views
2

使用的setInterval或RequestAnimationFrame,我想從X和Y之間 假設lerping X是0取得進展值和Y是1,我想有0啓動時,在半0.5和​​1等結束了。 我想在給定的時間內發生這種情況,比如5秒鐘。這意味着當setInterval/RequestAnimationFrame達到2.5秒時,將發生半值0.5。 最後,我想它喜歡乒乓球,因此當它達到5秒值會減少,不增加,例如如 0.9,0.8,0.7,等等,然後從0,0.1%,0.2重新開始...如何在兩個值X,Y之間來回循環?

任何提示或建議?

謝謝!

+1

您是否嘗試過的東西?你卡在哪裏? –

+0

詳細說明@AramilRey提出的問題;你有什麼嘗試?你做了什麼研究?你能提供片段來證明你實際上試圖自己解決問題嗎? (一個簡單的谷歌搜索將爲你提供解決這個問題所需的知識。)你不應該依靠SO社區爲你做你的工作。 –

+0

http://jsbin.com/picuwe/2/edit?js,output – punkbit

回答

5

爲線性內插的基本公式將像

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

其中XY是本值要被內插之間和t01確定內插的程度之間的參數; 0產量X1產量Y。此外,您希望週期性移動一段週期長度爲5的交替插值方向;這可以如下實現。如果t是一個非負數增長隨着時間的推移,計算

t' = t - t/10 

,除去已經發生的所有前期和

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

事後設置

t''' = t'/5 

的參數標準化爲[0,1]並從頭開始使用基本插值公式。

注意,線性內插和各種其它方法被收集here

1

從你的描述,在任何給定幀有6個狀態的:

  1. 電流線性插值
  2. 線性插值的時間跨度
  3. 電流方向
  4. 當前時間
  5. Start值的開始時間
  6. 結束值

從這些可以計算出所需的進步價值,說:

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

對於requestAnimationFrame,you need a simple callback to pass in。也就是說,函數必須知道它需要的所有東西,除了它在運行時可以獲得的東西。在這裏,它運行時只需要獲得當前時間,並從那裏開始工作。

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函數來調用,或事實上的回調,這樣你就可以採取任何元素,繪製函數和設置函數並創建一個動畫,但這是一個合理的起點。

有了上面的內容,我們只需要調用Mother來創建一個animableThing函數並調用RequestAnimationFrame。從那以後,它在內部調用RequestAnimationFrame來繼續循環。

現在,已經做到這一點,你會希望把它停下來,所以加在它可以檢查回調變量,所以,你可以做

var animableThing = MotherOfAnimableThings(...); 
window.requestAnimationFrame(animableThing); 
// ... later 
animableThing.stop = true; // it should stop on the next frame 
相關問題