捲軸繫結效果基礎知識
簡介
amp-position-observer 搭配 amp-animation 是一個強大的建構區塊,可以處理各種使用案例,例如捲軸繫結動畫、視差效果和轉場效果,因為元素會進入和離開可視區域。
在本教學課程中,我們將詳細介紹其中一些使用案例。
設定
amp-position-observer 是一個功能性元件,可監控元素在可視區域內的位置 (當使用者捲動時),並分派 enter
、exit
和 scroll:<Position In Viewport As a Percentage>
事件。
這些事件反過來可用於 play
、pause
或 seek
由 amp-animation 定義的動畫時間軸,以建立捲軸繫結和基於可見性的效果。
<script async custom-element="amp-position-observer" src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js"></script>
amp-animation 是一個 UI 元件,依賴 Web Animations API 在 AMP 文件中定義和執行關鍵影格動畫。
<script async custom-element="amp-animation" src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>
樣式
這些範例使用的 CSS 包含在此處以供參考。
這些規則只是讓範例運作的必要條件,並非此處涵蓋概念的基礎。
<style amp-custom>
/*
* Fidget Spinner styles
*/
.fidget-spinner-scene {
margin: 10px 20%;
}
/*
* Card transition styles
*/
.card {
margin: 10%;
position: relative;
}
.card-title {
padding: 5%;
padding-right: 40%;
font-size: 50%;
font-weight: bold;
color: #FAFAFA;
transform: translateX(-100%);
}
/*
* Parallax window styles
*/
.parallax-image-window {
overflow: hidden;
}
.parallax-image-window amp-img {
margin-bottom: -30%;
}
/*
* Carousel transition styles
*/
.carousel-component {
margin-right: -60%;
margin-left: 60%;
}
.carousel-parent {
overflow: hidden;
}
</style>
捲軸繫結動畫
讓我們建立一個指尖陀螺,在使用者捲動頁面時旋轉。
此範例展示結合 amp-position-observer
和 amp-animation
背後的核心概念:當元素透過捲動在可視區域中移動時,能夠在關鍵影格動畫時間軸中推進。
我們的指尖陀螺場景是一個包含 image
的 div
。我們新增一個 amp-position-observer
元素作為場景的子元素,以監控其在可視區域中的進度。讓我們看一下詳細資訊
on:scroll
:當使用者捲動時,場景的位置變更時,位置觀察器會觸發此事件。此事件提供一個百分比值 (0 到 1 之間的小數),代表場景在可視區域中從開始到結束進度的距離。spinAnimation.seekTo(percent=event.percent)
:我們將定義一個amp-animation
,在下一步中進行旋轉,這裡我們透過在scroll
事件發生時在動畫上觸發seekTo
動作,將amp-position-observer
和amp-animation
耦合在一起。這就是我們指定我們希望隨著場景透過捲動在可視區域中移動時,在動畫時間軸中推進的方式。intersection-ratios
:定義在amp-position-observer
觸發其任何事件之前,場景應在可視區域中可見多少。在這裡,我們希望僅在指尖陀螺完全可見時才發生旋轉,因此我們將其設定為1
。
<div class="fidget-spinner-scene">
<amp-position-observer on="scroll:spinAnimation.seekTo(percent=event.percent)" intersection-ratios="1" layout="nodisplay">
</amp-position-observer>
<amp-img id="fidgetSpinnerImage" width="1024" height="1114" layout="responsive" src="/static/samples/img/fidget.png" alt="Picture of a fidget spinner"></amp-img>
</div>
現在我們需要定義動畫本身
在這種情況下非常簡單,我們希望 fidgetSpinnerImage
旋轉 360 度,因此我們只需定義 "transform": "rotate(360deg)"
作為最後一個 (也是唯一一個) 關鍵影格。讓我們看一下詳細資訊
id="spinAnimation"
:我們需要為動畫指定一個 Id,以便我們可以從位置觀察器參考它。"duration": "1"
:duration
的值在這種情況下無關緊要,因為我們透過捲動在時間軸中推進,因此我們只需將其設定為1
"direction": "reverse"
:由於 iOS 中 Web Animations 存在錯誤,因此需要這樣做。"animations"
:在這裡我們可以定義一個或多個基於關鍵影格的動畫。在我們的案例中,我們只需要一個。"selector"
:"#fidgetSpinnerImage"
是動畫目標指尖陀螺的選取器。"keyframes":
我們定義"transform": "rotate(360deg)"
作為最後一個 (也是唯一一個) 關鍵影格。請注意,如果未提供第一個關鍵影格,amp-animation
會自動填寫。
amp-animation
具有許多其他功能,請參閱 API 參考資料以瞭解有關 amp-animations
的更多資訊。
<amp-animation id="spinAnimation" layout="nodisplay">
<script type="application/json">
{
"duration": "1",
"fill": "both",
"direction": "reverse",
"animations": [
{
"selector": "#fidgetSpinnerImage",
"keyframes": [
{ "transform": "rotate(360deg)" }
]
}
]
}
</script>
</amp-animation>
淡入和滑動轉場效果
現在我們已經瞭解了 amp-position-observer
和 amp-animation
背後的基本核心概念,讓我們深入探討更多創意的組合方式,以建立有趣的轉場效果。
在此範例中,我們將時間繫結和捲軸繫結轉場效果結合在一起,以建立一種效果,其中卡片的透明度與卡片在可視區域中可見的程度 (捲軸繫結) 相關聯,並且當卡片進入和離開可視區域時,卡片的標題會動畫顯示 (時間繫結)。
我們的卡片場景僅由影像和覆蓋的標題組成。在這裡,我們定義了兩個具有不同 intersection-ratios
值的位置觀察器
- 第一個將在使用者捲動時控制影像的透明度。
- 第二個將在場景變得大部分可見 (80%) 時,為標題執行時間繫結滑動動畫,並在場景稍微離開可視區域 (20%) 時再次「反向」執行。
<div class="card ampstart-card">
<amp-position-observer on="scroll:fadeTransition.seekTo(percent=event.percent)" intersection-ratios="0" layout="nodisplay">
</amp-position-observer>
<amp-position-observer on="enter:slideTransition.start; exit:slideTransition.start,slideTransition.reverse" intersection-ratios="0.8" layout="nodisplay">
</amp-position-observer>
<amp-fit-text layout="fill">
<div class="card-title">
Organic, fresh tomatoes and pasta!
</div>
</amp-fit-text>
<amp-img id="cardImage" width="1280" height="898" layout="responsive" src="/static/samples/img/food.jpg" alt="Picture of food table."></amp-img>
</div>
讓我們定義捲軸繫結淡入/淡出轉場效果的關鍵影格。
我們以 #cardImage
為目標,並以影像在時間軸的前 40% 內獲得完全不透明度,並在時間軸的後 40% 內開始淡出的方式定義關鍵影格。
請注意,由於控制此動畫的位置觀察器的 intersection-ratios
設定為 0
,因此當使用者捲動 ViewportHeight + 2 * SceneHeight
像素量時,我們會經歷完整的時間軸。
<amp-animation id="fadeTransition" layout="nodisplay">
<script type="application/json">
{
"duration": "1",
"fill": "both",
"direction": "reverse",
"animations": [
{
"selector": "#cardImage",
"keyframes": [
{ "opacity": "0.3", "offset": 0 },
{ "opacity": "1", "offset": 0.4 },
{ "opacity": "1", "offset": 0.6 },
{ "opacity": "0.3", "offset": 1 }
]
}
]
}
</script>
</amp-animation>
對於標題的滑入/滑出效果,我們只需定義一個 500 毫秒的動畫,該動畫將沿 X 軸移動標題。
當場景大部分可見/不可見時,此動畫將僅透過第二個位置觀察器觸發 (以正常或反向方向)。
<amp-animation id="slideTransition" layout="nodisplay">
<script type="application/json">
{
"duration": "500ms",
"fill": "both",
"easing": "ease-out",
"iterations": "1",
"animations": [
{
"selector": ".card-title",
"keyframes": [
{ "transform": "translateX(-100%)" },
{ "transform": "translateX(0)" }
]
}
]
}
</script>
</amp-animation>
視差影像視窗
視差是結合 amp-animation
和 amp-position-observer
可能實現的另一種效果。
視差通常涉及在使用者捲動時沿 Y 軸平移元素。
在這裡,我們定義一個場景,其高度小於其中的影像,當使用者捲動時,我們會移動影像,從而在影像中建立視差視窗。
<div class="parallax-image-window">
<amp-position-observer on="scroll:parallaxTransition.seekTo(percent=event.percent)" intersection-ratios="0" layout="nodisplay">
</amp-position-observer>
<amp-img id="parallaxImage" width="1280" height="873" layout="responsive" src="/static/samples/img/elephant.jpg" alt="Picture of an elephant"></amp-img>
</div>
動畫本身只是透過 "transform": "translateY(-30%)"
向上移動影像
<amp-animation id="parallaxTransition" layout="nodisplay">
<script type="application/json">
{
"duration": "1",
"fill": "both",
"direction": "reverse",
"animations": [
{
"selector": "#parallaxImage",
"keyframes": [
{ "transform": "translateY(-30%)" }
]
}
]
}
</script>
</amp-animation>
輪播轉場效果
我們也可以將這些效果與其他 AMP 元件 (例如 amp-carousel
) 搭配使用。
在此範例中,我們有一個輪播,其中第一個項目被推到右側,當輪播變得可見時,它會彈回原位,提供輪播可水平捲動的視覺「提示」。
<div class="carousel-parent">
<amp-carousel class="carousel-component" height="300" layout="fixed-height" type="carousel">
<amp-position-observer on="enter:carouselTransition.start" intersection-ratios="0.8" layout="nodisplay">
</amp-position-observer>
<amp-img src="https://unsplash.it/800/600?image=1003" width="400" height="300" alt="a sample image"></amp-img>
<amp-img src="https://unsplash.it/800/600?image=1043" width="400" height="300" alt="another sample image"></amp-img>
<amp-img src="https://unsplash.it/800/600?image=1032" width="400" height="300" alt="and another sample image"></amp-img>
</amp-carousel>
</div>
在這裡,我們定義了具有 200 毫秒延遲的時間繫結動畫,該動畫將在 500 毫秒內將輪播滑動到左側。
此動畫將僅由位置觀察器觸發一次,如上所述。
<amp-animation id="carouselTransition" layout="nodisplay">
<script type="application/json">
{
"duration": "500ms",
"fill": "both",
"easing": "ease-in",
"delay": "200ms",
"animations": [
{
"selector": ".carousel-component",
"keyframes": [
{ "transform": "translateX(-60%)" }
]
}
]
}
</script>
</amp-animation>
如果此頁面上的說明未涵蓋您的所有問題,請隨時與其他 AMP 使用者聯繫,討論您的確切使用案例。
前往 Stack Overflow 未說明的特色功能?AMP 專案強烈鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的長期參與者,但我們也歡迎針對您特別熱衷的問題做出一次性貢獻。
在 GitHub 上編輯範例-
作者: @aghassemi