AMP
  • 網站

滾動綁定效果基礎

簡介

amp-position-observer 結合 amp-animation 是一個強大的建構區塊,可以處理各種使用案例,例如滾動綁定動畫視差效果轉場效果,因為元素進入和退出 viewport。

在本教學中,我們將詳細介紹其中一些使用案例。

設定

amp-position-observer 是一個功能元件,可監控元素在 viewport 內的位置,因為使用者滾動,並發送 enterexitscroll:<Position In Viewport As a Percentage> 事件。

這些事件反過來可用於播放、暫停或搜尋由 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-observeramp-animation 背後的核心概念:當元素透過滾動在 viewport 中移動時,能夠在關鍵影格動畫時間軸中推進。

我們的指尖陀螺場景是一個帶有圖片的 div。我們新增一個 amp-position-observer 元素作為場景的子元素,以監控其在 viewport 中的進度。讓我們看看細節

  • on:scroll:當使用者滾動時,場景的位置發生變化時,位置觀察器會觸發此事件。該事件提供一個百分比值(介於 0 和 1 之間的小數),表示場景在其在 viewport 中的進度的開始和結束之間的位置。
  • spinAnimation.seekTo(percent=event.percent):我們將在下一步定義一個 amp-animation 來完成旋轉,這裡我們透過在滾動事件發生時在動畫上觸發 seekTo 動作,將 amp-position-observeramp-animation 耦合在一起。這就是我們指定我們希望在場景透過滾動在 viewport 中移動時,在動畫時間軸中推進的方式。
  • intersection-ratios:定義在 amp-position-observer 觸發其任何事件之前,場景應在 viewport 中可見多少。在這裡,我們希望旋轉僅在指尖陀螺完全可見時發生,因此我們將其設定為 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":這是由於 Web Animations 的 iOS 錯誤所必需的。
  • "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-observeramp-animation 背後的基本核心概念,讓我們深入了解可以將它們組合在一起以創建有趣轉場效果的更多創意方式。

在此範例中,我們將時間綁定和滾動綁定轉場效果結合在一起,以創建一種效果,其中卡片的透明度與其在 viewport 中可見的程度(滾動綁定)相關聯,並且卡片的標題在卡片進入和退出 viewport 時淡入/淡出(時間綁定)。

我們的卡片場景僅由圖片和覆蓋的標題組成。在這裡,我們定義了兩個具有不同 intersection-ratios 值的定位觀察器

  • 第一個將在使用者滾動時控制圖片的透明度。
  • 第二個將在場景變得大部分可見 (80%) 時為標題運行時間綁定滑動動畫,並在場景稍微退出 viewport 時再次 "反向" 運行 (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-animationamp-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 上編輯範例