運用承諾來協調動畫、透過可替換的動畫提升效能,以及使用複合模式讓動畫更流暢等等。
只要使用得當,動畫可以提升使用者對品牌的觀感和記憶、引導使用者採取行動,並協助使用者在數位空間中瀏覽您的應用程式。
Web Animation API 這項工具可讓開發人員使用 JavaScript 編寫動畫動畫。這個 API 旨在奠定 CSS 動畫和轉場效果的導入基礎,方便開發日後的特效,也能設計日後的組合效果和定時性。
雖然 Firefox 和 Safari 已經導入完整的規格功能,但 Chromium 84 仍將先前不支援的功能導入 Chrome 和 Edge,進一步實現跨瀏覽器互通性。
開始使用
如果您曾使用 @keyframe
規則,透過 Web Animation API 建立動畫的方式應會很熟悉。首先必須先建立一個主要畫面格物件在 CSS 中,看起來可能會像這樣:
@keyframes openAnimation {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
const openAnimation = [
{ transform: 'scale(0)' },
{ transform: 'scale(1)' },
];
您可在 CSS 中設定動畫參數的位置:
.modal {
animation: openAnimation 1s 1 ease-in;
}
則應在 JS 中設定:
document.querySelector('.modal').animate(
openAnimation, {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: 'ease-in' // easing function
}
);
程式碼數量大致相同,但只要搭配 JavaScript,就算只使用 CSS 也不例外。這包括設定順序效果,以及加強控制其播放狀態。
element.animate()
之後
不過,經過更新後,Web Animations API 不再僅限於透過 element.animate()
建立的動畫。我們也可以操控 CSS 動畫和轉場效果。
getAnimations()
是一種方法,會傳回元素中的所有動畫,不論元素是透過 element.animate()
還是透過 CSS 規則 (CSS 動畫或轉換) 建立。其外觀範例如下:
首先,"get"
做為轉場效果的主要畫面格,用來決定轉換來源。接著,建立兩個新的不透明度動畫,啟用交叉淡出效果。交叉淡出效果完成後,即可刪除副本。
依承諾編排動畫
在 Chromium 84 中,您現在有 animation.ready
和 animation.finished
這兩種承諾使用的方法。
animation.ready
可讓您等待待處理的變更生效,也就是切換播放和暫停等播放控制項方法。animation.finished
可讓您在動畫結束時執行自訂 JavaScript 程式碼。
讓我們繼續使用範例,並使用 animation.finished
建立自動化調度管理的動畫鏈結。在本例中,這是垂直轉換 (scaleY
),後面接著水平轉換 (scaleX
),然後是子項元素的不透明度變更:
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});
我們先使用 animation.finished.then()
鏈結這些動畫,然後才執行鏈結中的下一個動畫集。這樣一來,動畫就會按順序顯示,您甚至可以對不同的目標元素套用不同的選項設定 (例如速度和容易)。
在 CSS 中,重新建立會相當麻煩,特別是將不重複且連續的動畫套用至多個元素時。您必須使用 @keyframe
、排序正確的時間百分比才能放置動畫,並使用 animation-delay
才能依序觸發動畫。
例:播放、暫停及倒轉
可以開啟的東西,應該就能關閉了!幸好,自 Chromium 39 起,Web Animation API 讓我們可以播放、暫停及反轉動畫。
您可以擷取上述動畫,然後使用 .reverse()
再次點選該按鈕時,呈現流暢、反向的動畫。如此一來,您可以為我的互動視窗提供更順暢、更符合情境的互動功能。
您可以建立兩個待播放的動畫 (openModal
和內嵌不透明度轉換),然後暫停其中一個動畫,並延後其中一個動畫,直到另一個動畫完成為止。然後,您可以使用承諾,等待每個項目都結束之後,再開始玩。最後,您可以查看是否已設定旗標,然後反轉每個動畫。
範例:與部分主要畫面格的動態互動
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
在這個範例中,只有一個主要畫面格,沒有指定起始位置。以下示範如何使用部分主要畫面格。滑鼠處理常式會執行下列作業:設定新的結束位置並觸發新的動畫。系統會從目前的基礎位置推斷新的起始位置。
你可以在現有的轉場效果執行期間觸發新的轉場效果。這表示目前的轉換作業已中斷,並建立新的轉換。
利用可替換的動畫提升效能
根據事件 (例如 'mousemove'
) 建立動畫時,每次都會建立新的動畫,藉此快速消耗記憶體並降低效能。為解決這個問題,Chromium 第 83 版推出可替換的動畫,藉此啟用自動清理功能,將結束的動畫標記為可替換,並在其他已結束的動畫替換為其他播放完畢的動畫時,自動移除。請參考以下範例:
elem.addEventListener('mousemove', evt => {
rectangle.animate(
{ transform: translate(${evt.clientX}px, ${evt.clientY}px) },
{ duration: 500, fill: 'forwards' }
);
});
每次滑鼠移動時,瀏覽器會重新計算小工具軌跡中每球的位置,並為這個新的點建立動畫。瀏覽器現在知道在下列情況中會移除舊動畫 (啟用替換功能):
- 動畫結束。
- 在複合順序中,有一個或多個動畫也已完成。
- 新動畫是為相同的屬性建立動畫效果。
您可以使用 anim.onremove
觸發計數器,找出每個已移除動畫的計數器,即可確切查看取代的動畫數量。
以下還有幾種方法可進一步控制動畫控制項:
animation.replaceState()
可讓您追蹤動畫為使用中、保留或已移除。animation.commitStyles()
會根據基礎樣式,以及在複合順序中更新元素的所有動畫。animation.persist()
會將動畫標示為無法取代。
使用複合模式,讓動畫更流暢
透過 Web Animations API,您現在可以設定動畫的複合模式,除了預設的「replace」模式之外,動畫形式可以是累加或累積。複合模式可讓開發人員編寫不同的動畫,並控管效果的組合方式。系統現在支援三種複合模式:'replace'
(預設模式)、'add'
和 'accumulate'
。
建立複合動畫時,開發人員可以撰寫簡短而獨特的效果,然後再將這些動畫組合在一起。在以下範例中,我們會對每個方塊套用旋轉和縮放主要畫面格,但只有一個調整是複合模式,以下新增選項:
在預設的 'replace'
複合模式中,最終動畫會取代轉換屬性,結尾為 rotate(360deg) scale(1.4)
。如果是 'add'
,複合會新增旋轉並將比例乘上,進而產生 rotate(720deg) scale(1.96)
的最終狀態。'accumulate'
會合併轉換,因而產生 rotate(720deg) scale(1.8)
。如要進一步瞭解這些複合模式的細節,請參閱網頁動畫規格中的 CompositeOperation 和 CompositeOperationOrAuto 列舉。
一起來看看 UI 元素範例:
這裡有兩個 top
動畫完成合成。第一種是巨集動畫,它將下拉式選單本身高度移動,就像從頁面頂端滑入的動作效果,呈現在第二層動畫效果;第二是微動畫,當點擊向底部時,則會出現一點彈跳的彈跳效果。使用 'add'
複合模式可使轉場效果更順暢。
const dropDown = menu.animate(
[
{ top: `${-menuHeight}px`, easing: 'ease-in' },
{ top: 0 }
], { duration: 300, fill: 'forwards' });
dropDown.finished.then(() => {
const bounce = menu.animate(
[
{ top: '0px', easing: 'ease-in' },
{ top: '10px', easing: 'ease-out' },
{ ... }
], { duration: 300, composite: 'add' });
});
Web Animation API 的下一步
這些新功能現在都在瀏覽器中新增動畫功能,管道即將推出更多新增功能。以下將進一步說明未來的規格資訊: