Chrome 39 版的網頁動畫播放控制項

今年初,Chrome 36 將 element.animate 方法納入更廣泛的網頁動畫規格中。如此一來,開發人員就能選擇以最合適的方式建立高效率的原生動畫,並依照自身需求選擇製作動畫及轉換效果。

為快速複習一下,以下將說明如何在畫面上為雲朵製作動畫,並在完成後使用回呼:

var player = cloud.animate([
    {transform: 'translateX(' + start + 'px)'},
    {transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
    console.info('Cloud moved across the screen!');
    startRaining(cloud);
};

光是這種做法就很容易,而且在建立動畫或轉場效果時,不妨將這套系統應用在工具箱上。不過,在 Chrome 39 版中,element.animate 傳回的 AnimationPlayer 物件新增了播放控制項功能。先前建立動畫後,您只能呼叫 cancel() 或監聽完成事件。

這些播放額外影片開啟了網頁動畫的功能,例如將動畫變成一般用途的工具,而非為轉場效果 (即「固定」或預先定義的動畫

暫停、倒轉或變更播放速率

讓我們先更新上述範例,以便在點選雲朵時暫停動畫:

cloud.addEventListener('mousedown', function() {
    player.pause();
});

您也可以修改 playbackRate 屬性:

function changeWindSpeed() {
    player.playbackRate *= (Math.random() * 2.0);
}

您也可以呼叫 reverse() 方法,這通常等同於反轉目前的 playbackRate (乘以 -1)。不過有幾個特殊情況:

  • 如果 reverse() 方法造成的變更會導致執行中的動畫有效結束,currentTime 也會反轉。舉例來說,如果將新的動畫反轉,整個動畫就會反向播放

  • 如果播放器暫停,動畫就會開始播放。

拖曳播放器

AnimationPlayer 現在允許在動畫執行期間修改其 currentTime。這個值通常會隨著時間增加 (如果 playbackRate 為負數,則會降低這個值)。這可能會允許從外部控制動畫的位置 (可能透過使用者互動)。這通常稱為「拖曳」

舉例來說,如果您的 HTML 網頁代表天空,而您想要以拖曳手勢來變更目前正在播放的雲朵的位置,您可以在文件中新增一些處理常式:

var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
    startEvent = event;
    startEventTime = players.currentTime;
    player.pause();
});
document.addEventListener('touchmove', function(event) {
    if (!startEvent) return;
    var delta = startEvent.touches[0].screenX -
        event.changedTouches[0].screenX;
    player.currentTime = startEventTime + delta;
});

拖曳文件時,currentTime 會隨之變更,反映與原始事件的距離。您也可以在手勢結束時恢復播放動畫:

document.addEventListener('touchend', function(event) {
    startEvent = null;
    player.play();
});

視滑鼠從網頁移開時的位置而定 (合併示範),上述事件甚至可能會與反轉行為結合。

與其根據使用者互動而拖曳 AnimationPlayer,其 currentTime 也可以顯示進度或狀態,例如顯示下載狀態。

此處的公用程式在於 AnimationPlayer 允許設定值,並讓基礎原生實作處理其進度視覺化。在下載情況下,動畫的時間長度可以設為總下載大小,currentTime 則設為目前下載的大小 (示範)。

UI 轉場效果和手勢

行動平台向來都是常見的手勢,包括拖曳、滑動、快速滑過等。這些手勢通常有共同的主題:可拖曳的 UI 元件,例如清單檢視的「提取即可重新整理」,或是從畫面左側粗糙的側欄。

無論是在電腦或行動裝置上,網頁動畫都可以輕鬆複製出類似的效果。舉例來說,當控制 currentTime 的手勢完成時:

var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);

var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
    var srcTime = player.currentTime;
    var dstTime = findNearest(setpoints, srcTime);
    var driftDuration = dstTime - srcTime;

    if (!driftDuration) {
    runCallback(dstTime);
    return;
    }

    var driftPlayer = target.animate(steps, {
    duration: duration,
    iterationStart: Math.min(srcTime, dstTime) / duration,
    iterations: Math.abs(driftDuration) / duration,
    playbackRate: Math.sign(driftDuration)
    });
    driftPlayer.onfinish = function() { runCallback(dstTime); };
    player.currentTime = dstTime;
});

即可建立另一個會執行「偏移」的動畫。這會在手勢完成時播放,一直到已知的理想目標之間。

這項機制會根據動畫的建立順序決定動畫的優先順序:在這種情況下,driftPlayer 的優先順序高於播放器。driftPlayer 完成後,其效果就會消失。但是,最終時間會與基礎玩家的目前時間相符,因此您的使用者介面會保持一致。

最後,如果你喜歡小貓,可以使用示範網頁應用程式展現這些手勢。這個介面適合行動裝置使用,並且會使用 polyfill 確保回溯相容性,因此請嘗試在行動裝置上載入網頁!

請前往 forth and element.animate

無論是要用於簡單的動畫,還是透過其他方式利用傳回的 AnimationPlayerelement.animate 方法都「立即」完全運作。

其他新式瀏覽器也可以透過輕量 polyfill 完整支援這兩項功能。此 polyfill 也會執行功能偵測,因此當瀏覽器廠商實作該規格時,此功能只會越來越迅速、更好。

此外,網頁動畫規格也將持續更新。如果想試用即將推出的功能,你也可以參閱更詳細的 polyfill:web-animations-next