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

山姆索羅德
Sam Thorogood

今年稍早,Chrome 36 將 Element.animate 方法納入範圍更廣的 Web Animations 規格。如此一來,就能有效率地編寫有效率的原生動畫,為開發人員選擇以最適合的方式製作動畫和轉換。

為了讓我們快速複習一下,您可以按照下列步驟,為畫面上的雲層新增動畫,並在完成後進行回呼:

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();
});

視滑鼠從網頁上移除的位置而定,這種做法甚至可以與反向行為合併 (組合示範)。

currentTime 也可用於顯示進度或狀態,例如顯示下載狀態,而不是為了回應使用者互動而拖曳 AnimationPlayer

這裡的公用程式是 AnimationPlayer 允許設定值,而基礎原生實作會處理其進度圖表。在下載中,動畫的時間長度可以設為總下載大小,currentTime 則設為目前下載的大小 (試用版)。

UI 轉換和手勢

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

有了網路動畫,就能在 YouTube 或行動版網頁上輕鬆重現這個類似效果。舉例來說,當手勢控制 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 完成後,其及其效果將會消失。但是,最終時間會與基礎玩家的 currentTime 相符,因此您的使用者介面將保持一致。

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

往前看 Element.animate

無論是使用簡易動畫,還是以其他方式利用傳回的 AnimationPlayerelement.animate 方法都是「現在」的石頭。

其他新版瀏覽器也透過輕量級 polyfill 完整支援這兩項功能。此 polyfill 也會執行功能偵測,因此隨著瀏覽器廠商實作規格,此功能的速度和效能會隨著時間越來越好。

網路動畫的規格也會繼續完善。如果你想試用即將推出的功能,現在也可以透過更詳細的 polyfill:web-animations-next 使用這項功能。