AMP
  • 廣告

堆疊與綁定廣告

摘要

使用 amp-bind 和 amp-selector 建立互動式「堆疊」廣告的 AMPHTML 廣告範例。

樣式

這是一個進階範例,需要一些樣式設定才能使其外觀和功能正常運作。

為了易於閱讀,此範例中使用了自訂 CSS 屬性和 calc()。這不是必要條件,因為此範例中所有 calc() 運算式的結果都可以手動或使用 CSS 預處理器替換。

<style amp-custom>
  /* Define constants for stack item dimensions */
  :root {
    --item-width: 230px;
    --item-height: 130px;
  }
  /* Root container for the entire visual area */
  .root-container {
    font-family: 'Roboto', sans-serif;
    font-size: 14px;
    background: #000;
    color: #fff;
    width: 100%;
    height: 100vh;
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  }
  /* Main area container */
  .main-container {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
  }
  /* Footer styling */
  .footer {
    background: #000;
    font-size: 12px;
    padding: 8px;
    line-height: 34px;
    display: flex;
    position: relative;
    z-index: 1;
  }
  .footer-logo {
    flex: 1;
  }
  .logo-img {
    display: block;
  }
  .button {
    text-decoration: none;
    text-transform: uppercase;
    padding: 0 12px;
    color: #fff;
    display: inline-block;
    background-color: #2979ff;
  }
  /*
   * We use empty div elements to fake the appearance of depth in the stack.
   * Each one of them is offset by 8px, which is why the width changes.
   */
  .stack-bg-item {
    height: calc(var(--item-height) - 4px);
    margin: calc(8px - var(--item-height)) auto 0;
    border-radius: 3px;
  }
  .stack-bg-item:nth-child(1) {
    background: rgba(255, 255, 255, 0.15);
    margin-top: 0;
    width: calc(var(--item-width) - 4 * 8px);
  }
  .stack-bg-item:nth-child(2) {
    background: rgba(255, 255, 255, 0.25);
    width: calc(var(--item-width) - 3 * 8px);
  }
  .stack-bg-item:nth-child(3) {
    background: rgba(255, 255, 255, 0.35);
    width: calc(var(--item-width) - 2 * 8px);
  }
  .stack-bg-item:nth-child(4) {
    background: rgba(255, 255, 255, 0.45);
    width: calc(var(--item-width) - 1 * 8px);
  }
  .stack-container {
    display: block;
    position: absolute;
  }
  .stack {
    height: var(--item-height);
    width: var(--item-width);
    margin: calc(5px - var(--item-height)) 0 5px;
  }
  /* Styling for actual stack items */
  .stack-item {
    height: var(--item-height);
    width: var(--item-width);
    background: rgba(255, 255, 255, 0.6);
    border-radius: 3px;
    padding: 2px;
    position: absolute;
    box-sizing: border-box;
    transition: 0.3s transform, 0.3s opacity;

    /*
     * Translate the stack item horizontally when not topmost or second
     * topmost, and set its opacity to 0 so it's out of view.
     */
    transform: translate(100px, 0);
    opacity: 0;
  }
  .stack-item:nth-child(even) {
    /*
     * We use negative translate for each even stack item to alternate the
     * animation effect.
     */
    transform: translate(-100px, 0);
  }
  /*
   * Style the second topmost stack item so it's displayed.
   * We scale it so it's smaller than the topmost element by 8px total, to
   * contribute to the illusion of depth.
   */
  .stack-item.second-topmost {
    transform: scale(calc(1 - (4px / var(--item-width)))) translate(0, 0);
    opacity: 0;
  }
  /*
   * Style the topmost stack item so it's in full-width and slightly offset
   * from the second topmost.
   */
  .stack-item.topmost {
    opacity: 1;
    transform: scale(1) translate(0, 4px);
    z-index: 1;
  }
  /* Styling for selector dots */
  .dots {
    text-align: center;
  }
  .dots-item {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 6px;
    background: #fff;
    margin: 0 2px;
  }
  .dots-item[selected] {
    background: #2979ff;
  }
  .bg-img-container {
    width: 100%;
  }
</style>

amp-bind 狀態設定

我們使用初始狀態來設定堆疊中的項目數量。

<amp-state id="config">
  <script type="application/json">
    {
      "length": 5
    }
  </script>
</amp-state>

主要容器

定義一個以 amp-img 作為背景的主要容器。

<div class="root-container">
  <div class="main-container">
    <div class="bg-img-container">
      <amp-img src="/static/samples/img/car-front.jpg"
        width="608"
        height="568"
        layout="responsive"
        class="bg-img"></amp-img>
    </div>

堆疊

AMP 具有事件和動作的系統。它使用特定領域語言來描述如何觸發動作。在此範例中,我們設定了 on 屬性,以便在點擊時變更 amp-bind 狀態。「selection」變數最初是未定義的,這表示第一次存取時,它將回退為零。使用餘數運算 (%) 是為了讓堆疊在最後一個元素位於頂部時循環回到零。

每個堆疊項目都有一個由 amp-bind 計算的條件式類別值 ([class])。這是為了判斷每個項目是堆疊中最頂層還是第二頂層的元素,以便可以適當地設定樣式。

有關 amp-bind 運算式語法的詳細資訊,請參閱此文件。

<div class="stack-container"
    role="button"
    on="tap:AMP.setState({selection: (selection + 1) % config.length})">
  <div class="stack-bg-item"></div>
  <div class="stack-bg-item"></div>
  <div class="stack-bg-item"></div>
  <div class="stack-bg-item"></div>
  <div class="stack">
    <div class="stack-item topmost"
        [class]="'stack-item' +
            (selection == 0 ? ' topmost' :
                (selection == config.length - 1 ? ' second-topmost' : ''))">
      <amp-img src="/static/samples/img/car-sideview.jpg"
          width="226"
          height="126"
          layout="fixed"></amp-img>
    </div>
    <div class="stack-item second-topmost"
        [class]="'stack-item' +
            (selection == 1 ? ' topmost' :
                (selection == 0 ? ' second-topmost' : ''))">
      <amp-img src="/static/samples/img/car-steeringwheel.jpg"
          width="226"
          height="126"
          layout="fixed"></amp-img>
    </div>
    <div class="stack-item"
        [class]="'stack-item' +
          (selection == 2 ? ' topmost' :
              (selection == 1 ? ' second-topmost' : ''))">
      <amp-img src="/static/samples/img/car-seats.jpg"
          width="226"
          height="126"
          layout="fixed"></amp-img>
    </div>
    <div class="stack-item"
        [class]="'stack-item' +
          (selection == 3 ? ' topmost' :
              (selection == 2 ? ' second-topmost' : ''))">
      <amp-img src="/static/samples/img/car-gauges.jpg"
          width="226"
          height="126"
          layout="fixed"></amp-img>
    </div>
    <div class="stack-item"
        [class]="'stack-item' +
          (selection == 4 ? ' topmost' :
              (selection == 3 ? ' second-topmost' : ''))">
      <amp-img src="/static/samples/img/car-engine.jpg"
          width="226"
          height="126"
          layout="fixed"></amp-img>
    </div>
  </div>

我們可以使用 amp-selector 為我們的堆疊顯示指示點。[selected] 屬性用於參考 amp-bind 狀態變數,以便指示器相應地變更。

<amp-selector
    layout="container"
    class="dots"
    disabled
    [selected]="selection">
  <div option="0" class="dots-item" selected></div>
  <div option="1" class="dots-item"></div>
  <div option="2" class="dots-item"></div>
  <div option="3" class="dots-item"></div>
  <div option="4" class="dots-item"></div>
</amp-selector>
</div>
</div>
<div class="footer">
<div class="footer-logo">
<amp-img src="/static/samples/img/car-logo.png"
    width="72"
    height="32"
    layout="fixed"
    alt="Howdy"
    class="logo-img"></amp-img>
</div>
<a href="https://amp.dev.org.tw/documentation/examples/" target="_blank" class="button">
Learn More
</a>
</div>
</div>
需要進一步說明嗎?

如果此頁面上的說明未涵蓋您的所有問題,請隨時與其他 AMP 使用者聯繫,討論您的確切使用案例。

前往 Stack Overflow
未說明的特性?

AMP 專案強烈鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的持續參與者,同時我們也歡迎針對您特別熱衷的問題提供一次性貢獻。

在 GitHub 上編輯範例