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

今年稍早,Chrome 36 推出了 element.animate 方法,這是更廣泛的 Web 動畫規格的一部分。這可讓開發人員以最適合的方式建立動畫和轉場效果,以便撰寫高效的本機動畫。

為便於快速複習,以下說明如何在畫面上製作雲朵動畫,並在完成時提供回呼:

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() 或監聽 finish 事件。

這些播放功能的新增功能讓 Web Animations 的功能更加多元,將動畫轉變為通用工具,而非僅限於轉場效果,例如「固定」或預先定義的動畫。

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

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

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 則設為目前下載的大小 (demo)。

UI 轉場效果和手勢

行動平台一直是常見手勢的領域,包括拖曳、滑動、快速滑動等。這些手勢通常有共同的動作:可拖曳的 UI 元件,例如清單檢視畫面的「滑動以重新整理」或從螢幕左側拖曳的側欄。

有了 Web Animations,您就能輕鬆在電腦或行動裝置上複製類似的效果。舉例來說,當控制 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 會優先於 player。driftPlayer 完成後,它及其效果就會消失。不過,最終時間會與底層播放器的 currentTime 相符,因此 UI 會保持一致。

最後,如果您喜歡小貓咪,我們有一個示範網頁應用程式,可讓您體驗這些手勢。這項工具支援行動裝置,並使用 polyfill 提供向下相容性,因此請嘗試在行動裝置上載入這項工具!

繼續使用 element.animate

element.animate 方法現在非常棒,無論是用於簡單的動畫,還是用於以其他方式利用傳回的 AnimationPlayer,都很實用。

這兩項功能也透過輕量版 polyfill,在其他現代瀏覽器中獲得全面支援。這個 polyfill 也會執行功能偵測,因此隨著瀏覽器供應商實作規格,這項功能會隨著時間推移而變得更快、更完善。

Web Animations 規格也將持續發展。如果您想試用即將推出的功能,現在也可以在更詳細的 polyfill:web-animations-next 中使用這些功能。