AMP
  • stories

Ken Burns

Introduction

Best known for his work on documentaries, Ken Burns developed a signature effect which consisted of a combination of panning and zooming over an image. It has since been used popularly. We can achieve this simple yet captivating effect by combining the 'pan' and 'zoom' animations in amp-story. Here's how to do it.

Ken Burns Effect

The general idea is to nest elements to combine the animations: the container element will animate the zoom, and the image inside the container will be animated with a panning.

  • Start by creating an <amp-story-page> with a <amp-story-grid-layer using the fill template.
  • Add a <div> element which will act as the image container. Set its style class to position:absolute. This will ensure image coordinates correspond to those of the viewport, which is important for the animation.
  • Set its animation to be animate-in="zoom-in" or animate-in="zoom-out" and its duration with "animate-in-duration=30s".

In this demo we use 30 seconds but your mileage may vary. Try experimenting with different values to see what works best for your desired results.

  • Inside this container, add an <amp-img> element with the src attribute pointing at your image, describe the size of the image with the width and height attributes of the <amp-img> element. Set layout="fixed" so that the image outsizes the screen real estate (We want to use a large image that can be panned over. We recommend 1600 x 1200 px or larger).
  • Animate the <amg-img> element using the animate-in="pan-right". (You can also use pan-left, pan-up, and pan-down). See amp-story animations list.

It's important that the image sets the panning animation, whereas the image container sets the zoom animation. Otherwise the dimensions of the image will change, causing undesired results in the animation.

Animations can help make your Web Story more visually exciting and engaging, but use them intentionally. Some users may find long, continuous animations distracting. Other users may have motion sensitivity and be adversely affected by excessive use of motion and parallax effects. To make content as accessible as possible, keep your entering animations short and cohesive.

<amp-story-page id="ken-burns-effect1">
  <amp-story-grid-layer template="fill">
    <div animate-in="zoom-in" animate-in-duration="30s" class="img-container">
      <amp-img id="ken-burns-img1" src="https://picsum.photos/1600/1200?image=1077" animate-in="pan-left" animate-in-duration="30s"
        layout="fixed" width="1600" height="1200" alt="...">
      </amp-img>
    </div>
  </amp-story-grid-layer>
</amp-story-page>

Using Multiple Images

You can even implement a slideshow transitioning between multiple pages using this effect.

Just combine the animations as described in the combining animations section. Remember all the elements being animated after certain animation must include the animate-in-after attribute. Including the children being animated. See below for the code sample.

We also reset the sizes of the nested <div> elements so that they don't change the dimensions used for the animations. See the img-container style class in the code sample.

Keep in mind results may vary depending on the image size and animations you use. Experiment with different animation durations and presets to see what you like best!

<amp-story-page id="ken-burns-effect2">
  <amp-story-grid-layer template="fill">
    <div animate-in="zoom-in" animate-in-duration="5s" class="img-container">
      <amp-img id="ken-burns-img2" src="https://picsum.photos/1600/1200?image=1078" animate-in="pan-right" animate-in-duration="5s"
        layout="fixed" width="1600" height="1200" alt="...">
      </amp-img>
    </div>
    <div animate-in="fade-in" animate-in-after="ken-burns-img2" animate-in-duration="1s" class="img-container">
      <div animate-in="zoom-out" animate-in-duration="5s" class="img-container" animate-in-after="ken-burns-img2">
        <amp-img id="ken-burns-img3" src="https://picsum.photos/1600/1200?image=1026" layout="fixed" width="1600" height="1200" animate-in="pan-down"
          animate-in-duration="5s" animate-in-after="ken-burns-img2" alt="...">
        </amp-img>
      </div>
    </div>
    <div animate-in="fade-in" animate-in-after="ken-burns-img3" animate-in-duration="1s" class="img-container">
      <div animate-in="zoom-in" animate-in-duration="5s" class="img-container" animate-in-after="ken-burns-img3">
        <amp-img id="ken-burns-img4" src="https://picsum.photos/1600/1200?image=1029" layout="fixed" width="1600" height="1200" animate-in="pan-right"
          animate-in-duration="5s" animate-in-after="ken-burns-img3" alt="...">
        </amp-img>
      </div>
    </div>
    <div animate-in="fade-in" animate-in-after="ken-burns-img4" animate-in-duration="1s" class="img-container">
      <div animate-in="zoom-out" animate-in-duration="5s" class="img-container" animate-in-after="ken-burns-img4">
        <amp-img id="ken-burns-img5" src="https://picsum.photos/1600/1200?image=1033" layout="fixed" width="1600" height="1200" animate-in="pan-up"
          animate-in-duration="5s" animate-in-after="ken-burns-img4" alt="...">
        </amp-img>
      </div>
    </div>
  </amp-story-grid-layer>
</amp-story-page>

If you want a slower movement for each image and don't want to wait for the first image to be done animating to start animating the second one, you can use the animate-in-delay attribute on the second image. Set it to the amount of seconds that you want the first image to display before the second image appears.

<amp-story-page id="ken-burns-effect3">
  <amp-story-grid-layer template="fill">
    <div>
      <div animate-in="zoom-in" animate-in-duration="30s" class="img-container">
        <amp-img src="https://picsum.photos/1600/1200?image=1078" animate-in="pan-right" animate-in-duration="30s" layout="fixed"
          width="1600" height="1200" alt="...">
        </amp-img>
      </div>
      <div animate-in="fade-in" animate-in-delay="5s" animate-in-duration="1s" class="img-container">
        <div animate-in="zoom-out" animate-in-duration="30s" class="img-container" animate-in-delay="5s">
          <amp-img src="https://picsum.photos/1600/1200?image=1026" layout="fixed" width="1600" height="1200" animate-in="pan-up" animate-in-duration="30s"
            animate-in-delay="5s" alt="...">
          </amp-img>
        </div>
      </div>
      <div animate-in="fade-in" animate-in-delay="10s" animate-in-duration="1s" class="img-container">
        <div animate-in="zoom-out" animate-in-duration="30s" class="img-container" animate-in-delay="10s">
          <amp-img src="https://picsum.photos/1600/1200?image=1029" layout="fixed" width="1600" height="1200" animate-in="pan-right"
            animate-in-duration="30s" animate-in-delay="10s" alt="...">
          </amp-img>
        </div>
      </div>
      <div animate-in="fade-in" animate-in-delay="15s" animate-in-duration="1s" class="img-container">
        <div animate-in="zoom-out" animate-in-duration="30s" class="img-container" animate-in-delay="15s">
          <amp-img src="https://picsum.photos/1600/1200?image=1033" layout="fixed" width="1600" height="1200" animate-in="pan-left"
            animate-in-duration="30s" animate-in-delay="15s" alt="...">
          </amp-img>
        </div>
      </div>
    </div>
  </amp-story-grid-layer>
</amp-story-page>
需要进一步说明?

如果此页面上的说明未能涵盖您的所有问题,欢迎与其他 AMP 用户取得联系,讨论您的具体用例。

前往 Stack Overflow
一项无法解释的功能?

AMP 项目强烈鼓励您参与并做出贡献!我们希望您能成为我们开放源代码社区的持续参与者,但我们也欢迎您对所热衷问题做出一次性贡献。

编辑 GitHub 上的示例