amp-position-observer
Description
Monitors the position of an element within the viewport as a user scrolls, and dispatches events that can be used with other AMP components.
Required Scripts
<script async custom-element="amp-position-observer" src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js"></script>
Supported Layouts
Usage
The amp-position-observer component monitors the position of an
element within the viewport as a user scrolls, and dispatches
enter, exit and scroll:<Position In Viewport As a Percentage> events (Low Trust Level), which can be used to trigger actions (Only Low Trust Actions) on other components (e.g., amp-animation).
The amp-position-observer component is only useful when used with other components and does not do anything on its own.
Currently, amp-animation and several video players in AMP are the only components that allow low-trust events to trigger their actions (e.g., starting an animation, seeking to a position within the animation, pausing a video, etc.).
Scroll-bound animations
The amp-animation component exposes a seekTo action that can be tied to the scroll event
of amp-position-observer to implement scroll-bound animations.
Example: Animation rotates as user scrolls
Imagine an animation where the hour hand of a clock rotates as the user scrolls the page.
<!-- An animation that rotates a clock hand 180 degrees. --> <!-- Note that we are NOT setting `trigger=visibility` since we will manually trigger the animation. --> <amp-animation id="clockAnim" layout="nodisplay"> <script type="application/json"> { "duration": "3s", "fill": "both", "direction": "alternate", "animations": [ { "selector": "#clock-scene .clock-hand", "keyframes": [ {"transform": "rotate(-180deg)"}, {"transform": "rotate(0deg)"} ] } ] } </script> </amp-animation> <!-- The clock container --> <div id="clock-scene"> <!-- Use amp-position-observer to tie the movement of the clock scene within the viewport to the timeline of the animation --> <amp-position-observer intersection-ratios="1" on="scroll:clockAnim.seekTo(percent=event.percent)" layout="nodisplay" > </amp-position-observer> <amp-img layout="responsive" width="2" height="1.5" src="./img/clock.jpg"> <div class="clock-hand"></div> </amp-img> </div>
Animation scenes that start/pause based on visibility in the viewport
The amp-animation component also exposes start and pause actions that can be tied to the
enter and exit events of amp-position-observer to control when an animation
starts/pauses based on visibility.
The amp-position-observer component exposes various visibility configurations such as
intersection-ratios and viewport-margins (similar to IntersectionObserver) that
can be used to fine-tune when the target is considered visible.
Example: Animation starts and pauses based on visibility
Consider the same clock animation, but this time the hand animates with time, except we like the animation to start when clock is at least 50% visible and pause as soon as clock becomes less than 50% visible.
<!-- An animation that rotates a clock hand 180 degrees. --> <!-- Note that we are NOT setting `trigger=visibility` since we will manually trigger the animation --> <!-- Also note that this is the same animation as the scroll-bound version above the animation is the same, just the triggering mechanism with `amp-position-observer` is different! --> <amp-animation id="clockAnim" layout="nodisplay"> <script type="application/json"> { "duration": "3s", "fill": "both", "direction": "alternate", "animations": [ { "selector": "#clock-scene .clock-hand", "keyframes": [ {"transform": "rotate(-180deg)"}, {"transform": "rotate(0deg)"} ] } ] } </script> </amp-animation> <!-- The clock container --> <div id="clock-scene"> <!-- Use amp-position-observer to tie the start/pause of the animation with the visibility of the scene. --> <amp-position-observer intersection-ratios="0.5" on="enter:clockAnim.start;exit:clockAnim.pause" layout="nodisplay" > </amp-position-observer> <amp-img layout="responsive" width="2" height="1.5" src="./img/clock.jpg"> <div class="clock-hand"></