重要事項:本文件不適用於您目前選取的格式 stories (網路故事)!
amp-animation
說明
定義並顯示動畫。
必要指令碼
<script async custom-element="amp-animation" src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>
支援的版面配置
用法
amp-animation
元件定義並執行自訂動畫和效果。它仰賴 Web Animations API。
amp-animation
元件會在 JSON 結構中定義動畫。最上層區段會宣告目標元素、執行條件、計時屬性和 keyframes effect (關鍵影格效果),藉此定義總體動畫。總體程序可以包含在 animations
陣列中定義的任意數量的動畫部分。動畫陣列中的動畫部分可以有自己的目標元素、執行條件、計時屬性和關鍵影格效果。
<amp-animation layout="nodisplay"> <script type="application/json"> { "selector": "#target-id", "duration": "1s", "iterations": "4", "fill": "both", "direction": "alternate", "animations": [ { "selector": ".target-class", "easing": "cubic-bezier(0,0,.21,1)", "keyframes": { "transform": "rotate(20deg)" } }, { "delay": "2s", "easing": "cubic-bezier(0,0,.21,1)", "keyframes": { "transform": "rotate(30deg)" } } ] } </script> </amp-animation>
如果動畫使用單一元素和單一關鍵影格效果,則組態會以單一動畫定義的形式生效。
<amp-animation layout="nodisplay"> <script type="application/json"> { "selector": "#target-id", "duration": "1s", "keyframes": {"opacity": 1} } </script> </amp-animation>
如果動畫使用多個元素,但沒有最上層動畫,則組態會以定義陣列的形式生效。
<amp-animation layout="nodisplay"> <script type="application/json"> [ { "selector": ".target1", "duration": 1000, "keyframes": {"opacity": 1} }, { "selector": ".target2", "duration": 600, "delay": 400, "keyframes": {"transform": "scale(2)"} } ] </script> </amp-animation>
透過 trigger
屬性或 動作,觸發一或多個動畫的開始。
您可以將透過動作控制的 amp-animation
放置在 DOM 中的任何位置。如果動畫包含 trigger="visibility"
,則會在父元素進入可視區域時觸發動畫,並在離開可視區域時暫停動畫。
定義效果
關鍵影格
您必須宣告效果為關鍵影格,才能使用 amp-animations
套用動畫。
您可以採用與 MDN 的 Keyframe Formats (關鍵影格格式) 中定義的相同方式,在 amp-animation 中指定關鍵影格。您也可以參照在 <style amp-custom>
或 <style amp-keyframes>
標記內定義為 CSS 的 @keyframes
名稱。
以下是一些關鍵影格定義的典型範例。
速記物件形式「to (到)」格式指定 100% 的最終狀態
{ "keyframes": {"opacity": 0, "transform": "scale(2)"} }
速記物件形式「from-to (從-到)」格式指定 0% 和 100% 的開始和最終狀態
{ "keyframes": { "opacity": [1, 0], "transform": ["scale(1)", "scale(2)"] } }
速記物件形式「value-array (值陣列)」格式指定開始、最終狀態和多個 (等間隔) 偏移量的多個值
{ "keyframes": { "opacity": [1, 0.1, 0], "transform": ["scale(1)", "scale(1.1)", "scale(2)"] } }
陣列形式指定關鍵影格。偏移量會自動指派為 0%、100% 和介於兩者之間的均勻間隔
{ "keyframes": [ {"opacity": 1, "transform": "scale(1)"}, {"opacity": 0, "transform": "scale(2)"} ] }
陣列形式也可以明確包含「offset (偏移量)」
{ "keyframes": [ {"opacity": 1, "transform": "scale(1)"}, {"offset": 0.1, "opacity": 0.1, "transform": "scale(2)"}, {"opacity": 0, "transform": "scale(3)"} ] }
陣列形式也可以包含「easing (緩和)」
{ "keyframes": [ {"easing": "ease-out", "opacity": 1, "transform": "scale(1)"}, {"opacity": 0, "transform": "scale(2)"} ] }
使用 @keyframes
CSS 規則
<style amp-custom> @keyframes keyframes1 { from { opacity: 0; } to { opacity: 1; } } </style> <amp-animation layout="nodisplay"> <script type="application/json"> { "duration": "1s", "keyframes": "keyframes1" } </script> </amp-animation>
大多數 CSS @keyframes
符合 Web Animations spec (Web Animations 規格) 中的 JSON 行內關鍵影格定義,但有以下細微差異
-
您可能需要供應商前置字串,例如
@-ms-keyframes {}
或-moz-transform
,以獲得廣泛的平台支援。JSON 格式中不需要且不允許供應商前置字串,但在 CSS 中可能需要。 -
在不支援的平台上,當搭配 CSS 中指定的關鍵影格使用
calc()
和var()
時,amp-animation
的 Polyfill 會失敗。在 CSS 中使用回溯值以避免這種情況。 -
CSS 擴充功能 (例如
width()
、height()
、x()
、y()
、num()
、rand()
、index()
和length()
) 不適用於@keyframes
。
關於 prefers-reduced-motion
通常,執行動畫會藉由將元素置於可見狀態來完成,而初始 CSS 會隱藏元素,以便稍後依賴動畫完成。
使用者可以將裝置設定為 使用減少的動畫。使用此選項時,動畫將完全不會執行。在這種情況下,您需要停用稍後依賴動畫執行的 CSS 屬性。
您可以將媒體查詢用於此目的。在以下範例中,<amp-animation>
稍後會透過設定 opacity: 1
將元素動畫化為可見狀態。當動畫停用時,元素始終可見
<style amp-custom> .my-hidden-element { opacity: 1; } @media not (prefers-reduced-motion) { .my-hidden-element { opacity: 0; } } </style> <amp-animation layout="nodisplay"> <script type="application/json"> [ { "selector": ".my-hidden-element", "duration": "1s", "keyframes": {"opacity": 1} } ] </script> </amp-animation>
關鍵影格的允許屬性
amp-animation 元件限制 CSS 允許的屬性以最佳化效能。以下是允許的屬性清單
opacity (不透明度)
transform (變形)
visibility (可見性)
offset-distance (偏移距離)
clip-path
。僅支援的值為inset()
、circle()
、ellipse()
和polygon()
。
不需要也不允許使用供應商前置字串 CSS 屬性。
計時屬性
最上層動畫和動畫元件可能包含計時屬性。以下是允許的屬性集
屬性 | 類型 | 預設值 | 說明 |
---|---|---|---|
duration (持續時間) | time (時間) | 0 | 動畫持續時間。數值 (毫秒) 或 CSS 時間值,例如 2s 。 |
delay (延遲) | time (時間) | 0 | 動畫開始執行前的延遲時間。數值 (毫秒) 或 CSS 時間值,例如 2s 。 |
endDelay (結束延遲) | time (時間) | 0 | 動畫完成後到實際視為完成前的延遲時間。數值 (毫秒) 或 CSS 時間值,例如 2s 。 |
iterations (重複次數) | 數字或 "Infinity (無限)" 或 "infinite (無限)" | 1 | 動畫效果重複的次數。 |
iterationStart (重複開始) | 數字/CSS | 0 | 效果開始動畫化的時間偏移量。 |
easing (緩和) | 字串 | "linear (線性)" | 用於縮放時間以產生緩和效果的 timing function (計時函式)。 |
direction (方向) | 字串 | "normal (正常)" | "normal (正常)"、"reverse (反向)"、"alternate (交替)" 或 "alternate-reverse (交替反向)" 其中之一。 |
fill (填滿) | 字串 | "none (無)" | "none (無)"、"forwards (向前)"、"backwards (向後)"、"both (兩者)"、"auto (自動)" 其中之一。 |
所有計時屬性都允許直接數值/字串值或 CSS 值。例如,1000
或 1s
或 1000m
都是 duration
的有效值。
JSON 中計時屬性的範例
{ ... "duration": "1s", "delay": 100, "easing": "ease-in", "fill": "both" ... }
動畫元件會繼承為最上層動畫指定的計時屬性。
變數和計算的運算式
amp-animation
允許針對計時和關鍵影格值使用 var()
、calc()
、min()
和 max()
運算式。
<amp-animation layout="nodisplay"> <script type="application/json"> [ { "selector": ".target-class", "duration": "4s", "delay": "var(--delay)", "--y": "var(--other-y, 100px)", "keyframes": {"transform": "translate(calc(100vh + 20px), var(--y))"} } ] </script> </amp-animation>
您可以宣告 CSS 變數,以透過 var()
運算式用於計時和關鍵影格值。
CSS 變數適用於巢狀動畫,但巢狀動畫可能會覆寫變數的值。
<amp-animation layout="nodisplay"> <script type="application/json"> { "--delay": "0.5s", "--x": "100px", "animations": [ { "selector": "#target1", "delay": "var(--delay)", "--x": "150px", "keyframes": {"transform": "translate(var(--x), var(--y, 0px)"} }, ... ] } </script> </amp-animation>
在以上範例中
-
巢狀動畫將變數
--delay
套用至#target1
動畫的延遲。 -
雖然
--x
會傳播到巢狀動畫中,但會遭到覆寫。最終的 translate 值為150px
。 -
<amp-animation>
元件中未指定--y
。如果查詢在<amp style-custom>
標記中找不到定義為 CSS 的--y
,則預設為0px
。
Polyfill 同時適用於支援平台上的 var()
和 calc()
。最佳做法是為 var()
包含預設值。
<amp-animation layout="nodisplay"> <script type="application/json"> [ { "selector": ".target-class", "duration": "4s", "delay": "var(--delay, 100ms)" } ] </script> </amp-animation>
使用 amp-animation
元件中的 --var-name
欄位,覆寫在 <style amp-custom>
標記中指定的目標元素的變數。var()
運算式會先嘗試解析動畫元件中指定的值,然後解析目標樣式。
CSS 擴充功能
amp-animation
元件提供以下 CSS 擴充功能:rand()
、num()
、width()
、height()
、x()
和 y()
。允許的 CSS 擴充功能在 amp-animation
定義中可以使用 CSS 值的所有位置都有效。這包括計時和關鍵影格值。
CSS index()
擴充功能
index()
函式會傳回動畫效果中目前目標元素的索引。當使用 selector
屬性為多個目標製作相同的效果動畫時,這最為相關。selector
比對到的第一個目標的 index
為 0,第二個目標的 index
為 1,依此類推。
除了其他用途外,此屬性還可以與 calc()
運算式結合以建立交錯效果。例如
{ "selector": ".class-x", "delay": "calc(200ms * index())" }
CSS length()
擴充功能
length()
函式會傳回動畫效果中目標元素的數量。這在與 index()
結合使用時最為相關
{ "selector": ".class-x", "delay": "calc(200ms * (length() - index()))" }
CSS rand()
擴充功能
rand()
函式會傳回隨機 CSS 值。有兩種形式。
不含引數的形式會傳回介於 0 和 1 之間的隨機數字。
{ "delay": "calc(10s * rand())" }
第二種形式有兩個引數,並傳回介於這兩個引數之間的隨機值。
{ "delay": "rand(5s, 10s)" }
CSS width()
、height()
、x()
和 y()
擴充功能
width()
/height()
和 x()
/y()
擴充功能會傳回動畫元素或選取器指定的元素的大小或座標。傳回的值以像素為單位,例如 100px
。
amp-animation
支援以下形式
-
width()
、height()
、x()
、y()
- 動畫元素的寬度/高度或座標。 -
使用選取器,例如
width('.selector')
或x('.selector')
- 選取器指定的元素的尺寸或座標。可以使用任何 CSS 選取器。例如,height('#container > li')
。 -
使用最接近的選取器,例如
height(closest('.selector'))
或y(closest('.selector'))
- 最接近的選取器指定的元素的尺寸或座標。
width()
和 height()
對於變形特別有用。left
、top
和類似的 CSS 屬性可以使用 %
值來表示與容器大小成比例的動畫。但是,transform
屬性會以不同的方式解譯 %
值,即選取元素的百分比。因此,width()
和 height()
可用於以容器元素和類似元素來表示變形動畫。
這些函式可以與 calc()
、var()
和其他 CSS 運算式結合使用。例如
{ "transform": "translateX(calc(width('#container') + 10px))" }
CSS num()
擴充功能
num()
函式會傳回 CSS 值的數字表示法。例如
num(11px)
產生11
;num(110ms)
產生110
;- 等等。
例如,以下運算式會計算與元素寬度成比例的延遲秒數
{ "delay": "calc(1s * num(width()) / 100)" }
覆寫子目標的效果
使用子目標覆寫最上層動畫中定義的計時屬性或變數。在所需位置透過 subtargets: []
定義子目標,與有效的 selector
位於相同的空間中。依索引或 CSS 選取器指定子目標。
{ "selector": ".target", "delay": 100, "--y": "100px", "subtargets": [ { "index": 0, "delay": 200 }, { "selector": ":nth-child(2n+1)", "--y": "200px" } ] }
在以上範例中
-
最上層動畫預設將
".target"
比對到的目標設定為100
的延遲和100px
的"--y"
。 -
"subtargets": []
包含第一個目標,"index": 0
。此定義將預設延遲100
覆寫為200
。 -
"subtargets": []
包含"selector": ":nth-child(2n+1)"
。此定義將--y
變數的預設值100px
覆寫為200px
。
多個子目標可以比對一個目標 selector
元素。
SVG 動畫
SVG 非常棒,我們建議將其用於動畫!
amp-animation
元件支援具有允許清單 CSS 關鍵影格屬性的 SVG 動畫,但有以下細微差異
-
IE/Edge SVG 元素 不支援 CSS
transform
屬性。雖然transform
動畫本身已 Polyfill,但未套用樣式表中定義的初始狀態。如果初始變形狀態在 IE/Edge 上很重要,建議透過 SVGtransform
屬性 複製。 -
不可能為 IE/Edge Polyfill
transform-origin
。為了相容性,請僅使用預設transform-origin
。 -
使用 CSS
transform-box
以避免transform-origin
解譯問題。請參閱 Chrome、Safari 和 Firefox 的問題。
相容性和回溯
使用媒體查詢、支援條件和 switch 陳述式以獲得平台相容性和回溯選項。
媒體查詢
使用 media
屬性指定媒體查詢。此屬性可以包含 Window.matchMedia API 允許的任何運算式,並對應於 @media
CSS 規則。
指定後,動畫元件只會在環境支援指定的 CSS 功能時執行。
Supports 條件
使用 supports
屬性指定 supports 條件。supports
屬性包含 CSS.supports
API 允許的任何運算式,並對應於 @supports
CSS 規則。
指定後,動畫元件只會在環境支援指定的 CSS 功能時執行。
動畫 switch
陳述式
在某些情況下,您可能需要將條件式動畫與選用的預設動畫合併到單一動畫中。使用 switch
動畫陳述式來定義條件。
{ // Optional selector, vars, timing ... "switch": [ { "media": "(min-width: 320px)", "keyframes": {...}, }, { "supports": "offset-distance: 0", "keyframes": {...}, }, { // Optional default: no conditionals } ] }
amp-animation
元件會依定義順序評估 switch
動畫定義。它會執行第一個符合條件的動畫,並忽略其餘動畫。
在以下範例中,動畫會在支援 motion-path 動畫時執行,並回溯到 transform
{ "selector": "#target1", "duration": "1s", "switch": [ { "supports": "offset-distance: 0", "keyframes": { "offsetDistance": [0, "300px"] } }, { "keyframes": { "transform": [0, "300px"] } } ] }
合併和分割動畫
amp-animation
中定義的動畫可以彼此參照。此功能允許將多個 amp-animation
宣告合併到單一動畫中。將動畫分割成不同的 amp-animation
元件可重複使用較小的動畫,同時啟用與巢狀相同的效果。
<amp-animation id="anim1" layout="nodisplay"> <script type="application/json"> { "animation": "anim2", "duration": 1000, "--scale": 2 } </script> </amp-animation> <amp-animation id="anim2" layout="nodisplay"> <script type="application/json"> { "selector": ".target-class", "keyframes": {"transform": "scale(var(--scale))"} } </script> </amp-animation>
以上範例動畫將 "anim2"
動畫合併為 "anim1"
的一部分。"anim2"
不需要 selector
目標。在這種情況下,包含的動畫會參照其自身的目標。
另一種形式允許包含的動畫提供目標或多個目標。在這種情況下,包含的動畫會針對每個比對到的目標執行。
<amp-animation id="anim1" layout="nodisplay"> <script type="application/json"> { "selector": ".target-class", "animation": "anim2", "duration": 1000, "--scale": 2 } </script> </amp-animation> <amp-animation id="anim2" layout="nodisplay"> <script type="application/json"> { "keyframes": {"transform": "scale(var(--scale))"} } </script> </amp-animation>
在以上範例中,"anim2"
會針對每個比對到的 ".target-class"
執行。在呼叫端動畫中指定的變數和計時屬性會傳遞至合併的動畫。
透過 on 動作觸發
例如
<amp-animation id="anim1" layout="nodisplay"> ... </amp-animation> <button on="tap:anim1.start">Animate</button>
動畫的無障礙考量
如果您使用動畫來傳達意義或內容,請確保也以其他形式為可能看不到這些動畫的使用者傳達相同的意義或內容。在最基本的層面上,請確保您的文字內容傳達與動畫相同的資訊。例如,如果您使用 <amp-animation>
來說明流程中的一系列步驟,請確保也有文字 (在同一頁面或連結頁面中) 以文字描述相同的步驟順序。
動畫通常無法由使用者暫停/停止。這可能會根據動畫的類型、大小以及是否循環/重複,對某些使用者群組 (特別是動畫包含快速閃爍的色彩變化時) 造成輕微的干擾或嚴重的問題。一般而言,我們建議避免使用大型、無限重複的動畫,除非您確定它們不會對使用者產生不利影響。考慮提供控制項以允許使用者暫停動畫。考慮利用 prefers-reduced-motion
媒體查詢,並且僅在使用者未表示偏好減少動作/動畫時才讓動畫生效。
<amp-animation ... media="not (prefers-reduced-motion: reduce)"> <!-- this animation will only play if the user has *not* expressed a preference for reduced motion --> ... </amp-animation>
您可以更進一步,提供當 prefers-reduced-motion: reduce
評估結果為 true 時生效的個別、更細微的回溯動畫,或拆分出在所有情況下都應發生的較小動畫,而無論媒體功能為何。
<amp-animation ... media="(prefers-reduced-motion: reduce)"> <!-- fallback subtle animation effects that only play if the user has expressed a preference for reduced motion --> ... </amp-animation> <amp-animation ...> <!-- general/common animation effects that will take effect regardless of any user preference for reduced motion --> ... </amp-animation>
如需更多詳細資訊,請參閱 MDN - prefers-reduced-motion
和這篇關於 web.dev - prefers-reduced-motion:有時少即是多 的介紹性文章。
對於並非純粹裝飾性/視覺效果,而是實際傳達資訊的動畫,請確保任何重要的文字和圖形/非文字元素都有足夠的色彩對比。如需簡介 (主要圍繞文字對比) 請參閱 web.dev 色彩和對比度無障礙功能,如需更多有關非文字元素的詳細資訊,請參閱 Knowbility:探索 WCAG 2.1 — 1.4.11 非文字對比。
屬性
trigger (觸發器)
決定何時應觸發動畫。必須將此設定為 visibility
,以便在故事頁面變為可見且處於活動狀態時啟動動畫。
layout (版面配置)
應始終為 nodisplay
。
id
(選填)
動畫元件的 id
。用於參照動畫並串連一系列動畫。
動作
start (開始)
如果動畫尚未執行,則開始動畫。計時屬性和變數。可以指定為動作引數。例如 anim1.start(delay=-100, --scale=2)
。
restart (重新開始)
開始動畫或重新開始目前正在執行的動畫。計時屬性和變數。可以指定為動作引數。例如 anim1.start(delay=-100, --scale=2)
。
pause (暫停)
暫停目前正在執行的動畫。
resume (繼續)
繼續目前正在執行的動畫。
togglePause (切換暫停)
切換暫停/繼續動作。
seekTo (搜尋到)
暫停動畫並搜尋到 time
引數 (以毫秒為單位) 或 percent
引數 (以時間軸中的百分點為單位) 指定的時間點。
reverse (反向)
反轉動畫。
finish (完成)
完成動畫。
cancel (取消)
取消動畫。
amp-story 用法
如果您想要將 <amp-animation>
與 <amp-story>
搭配使用,請注意您應該改用 <amp-story-animation>
。如需如何使用它的詳細資訊,請參閱文件中的 Advanced animations (進階動畫) 區段。
驗證
請參閱 AMP 驗證器規格中的 amp-animation
規則。
您已閱讀本文件十幾次,但它仍然沒有真正涵蓋您的所有問題嗎?也許其他人也有相同的感受:在 Stack Overflow 上與他們聯繫。
前往 Stack Overflow 發現錯誤或缺少功能?AMP 專案強烈鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的持續參與者,但我們也歡迎針對您特別感興趣的問題提供一次性的貢獻。
前往 GitHub