Scrollbound Slides 360 Ad

Edit on Github
Open in Playground View Demo

Experimental Mode

This example uses the following experimental features: [amp-animationamp-google-vrview-imageamp-lightbox-a4a-proto]. Enable the experiment via the button below. Some components require the AMP Dev Channel to be enabled as well. Learn more here.

Enable Dev Channel

Summary

Sample AMP Ad using amp-animation, amp-lightbox, amp-google-vrview-image, and amp-img to create an ad that changes slides based on scrolling and displays a 360 image in a lightbox.

Demo of this example

Styling

This is an advanced example that requires some styling to make it look and function properly. The styling designed here is responsive and will work with various ad sizes.

<style amp-custom>

  /*
   * Top level container: It fills the parent viewport
   * that hosts the ad.
   */
  .ad-container {
    font-family: "Roboto", sans-serif;
    width: 100vw;
    height: 100vh;
    color: #FFFFFF;
  }

  /* Content Layer */
  .content-container {
    z-index: 1;
  }

  /* Content Layer: Title and logo */
  .title {
    position: absolute;
    top: 40%;
    left: 0;
    padding: 15px;
    transform: translate(0, -40%);
    background: rgba(0,0,0,0.8);
    font-weight: bold;
  }

  .vr360-button {
    position: absolute;
    top: 40%;
    transform: translate(0, -40%);
    height: auto;
    right: 0px;
    display: flex;
    flex-direction: row;
  }

  .vr360-button>* {
    flex: 1;
  }

  .next {
    padding: 2px;
    margin-left: 2px;
    background-repeat: no-repeat;
    background-position: center center;
    background-image: url('https://ampbyexample.com/img/arrow.svg');
    transform: rotate(180deg);
    background-size: contain;
  }

  /* Content Layer: Footer and learn more button */
  .footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 5px 10px;
    background-color: rgba(0, 0, 0, 0.8);
    box-sizing: border-box;
    font-size: 10px;
    display: flex;
    flex-direction: row;
  }

  .footer>* {
    flex: 1;
    align-self: center;
  }

  .footer>.center {
    flex: 2;
  }

  .logo {
    margin-right: 10px;
  }

  .button {
    flex: 0;
    font-size: 10px;
    background-color: #2979ff;
    padding: 5px 15px;
    white-space: nowrap;
    letter-spacing: 0.5px;
    color: #fafafa;
    text-decoration: none;
    cursor: pointer
  }

  /* Generic CSS class to fill a parent */
  .fill {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  }

  /* Lightbox styles */
  .lightbox-back-button {
    position: absolute;
    z-index: 1;
    cursor: pointer;
    width: 60px;
    height: 60px;
    background-repeat: no-repeat;
    background-position: center center;
    background-image: url('https://ampbyexample.com/img/arrow.svg');
  }

  #lightbox-vr {
    background: #f9f7f7;
  }

  .ad-container img {
    object-fit: cover;
  }

</style>

Scrollbound Slide Change Animation

The animation is implemented using amp-animation which is an experimental AMP component that uses Web Animations API to support both time and scroll based animations.

<amp-animation layout="nodisplay"
  trigger="visibility">
  <script type="application/json">
    {
      "ticker": "scroll",
      "fill": "both",
      "animations": [{
        "target": "slides",
        "keyframes": [{
            "transform": "translateY(0)"
          },
          {
            "transform": "translateY(0)",
            "offset": 0.5
          },
          {
            "transform": "translateY(-100vh)",
            "offset": 0.5
          },
          {
            "transform": "translateY(-100vh)",
            "offset": 1
          }
        ]
      }]
    }
  </script>
</amp-animation>

scroll vs. time ticker: Setting "ticker": "scroll" tells amp-animation to advance the animation timeline based on scrolling rather than time.

Sliding images: We have two images of 100vh height for this ad, we switch between them by moving the parent container -100vh at the middle keyframe of the scrollbound animation as defined above.

The amp-lightbox component defines the child elements that will be displayed in a full-viewport overlay. We set a different id for each lightbox so they can be opened and closed by actions on other elements.

Inside the lightbox we create an amp-google-vrview-image component which can display VR and 360 images and videos.

<amp-lightbox id="lightbox-vr"
  layout="nodisplay">
  <div class="lightbox-back-button"
    role="button"
    tabindex="0"
    on="tap:lightbox-vr.close">
  </div>
  <amp-google-vrview-image yaw="90"
    src="https://ampbyexample.com/img/car-vr-360.jpg"
    layout="fill">
  </amp-google-vrview-image>
</amp-lightbox>

Ad Container

Top level container: It fills the parent viewport that hosts the ad.

amp-ad-banner is a dummy AMP element that is used by the AMP runtime to determine the position of the ad when a lightbox is opened.

<amp-ad-banner class="ad-container"
  layout="container">

Content Layer

Create the content layer that hosts the slide images and information about the ad.

<div class="content-container fill">
  <div id="slides">
    <amp-img height="100vh"
      layout="fixed-height"
      src="https://ampbyexample.com/img/car-side-bg.jpg"></amp-img>
    <amp-img height="100vh"
      layout="fixed-height"
      src="https://ampbyexample.com/img/car-tunnel.jpg"></amp-img>
  </div>
  <div class="title">
    <div>THE ALL NEW</div>
    <div>HOWDY WS-X LUX</div>
  </div>
  <div class="vr360-button"
    on="tap:lightbox-vr.activate"
    role="button"
    tabindex="0">
    <div class="button">EXPLORE 360</div>
    <div class="button next"></div>
  </div>
  <div class="footer">
    <div>
      <amp-img class="logo"
        layout="fixed"
        width="72"
        height="32"
        src="https://ampbyexample.com/img/car-logo.png"></amp-img>
    </div>
    <div class="center">
      <span>36 months lease, $189/month, $2999 due at signing</span>
    </div>
    <div>
      <a href="https://ampproject.org"
        target="blank_"
        class="button">LEARN MORE</a>
    </div>
  </div>
</div>