AMP
  • 广告

带有绑定广告的堆叠

摘要

使用 amp-bindamp-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.org.cn/documentation/examples/" target="_blank" class="button">
Learn More
</a>
</div>
</div>
需要进一步解释?

如果此页面上的说明没有涵盖您所有的问题,请随时与其他 AMP 用户联系,讨论您的具体用例。

转到 Stack Overflow
未解释的功能?

AMP 项目强烈鼓励您的参与和贡献!我们希望您能成为我们开源社区的长期参与者,但我们也欢迎您对您特别感兴趣的问题进行一次性贡献。

在 GitHub 上编辑示例