amp-position-observer
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 Script | <script async custom-element="amp-position-observer" src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js"></script> |
Supported Layouts | nodisplay |
Examples |
Overview
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.
What can I do with amp-position-observer?
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"></div> </amp-img> </div>
Attributes
target (optional) | Specifies the ID of the element to observe. If not specified, the parent of <amp-position-observer> is used as the target. |
intersection-ratios (optional) | Defines how much of the target should be visible in the viewport before You can specify different ratios for top vs. bottom by providing two values (
|
viewport-margins (optional) | A You can specify different values for top vs. bottom by providing two values (
|
once (optional) | Only triggers the enter and exit events once. The scroll event will also only perform one iteration.
The presence of the attribute represents the |
Validation
See amp-position-observer rules in the AMP validator specification.
You've read this document a dozen times but it doesn't really cover all of your questions? Maybe other people felt the same: reach out to them on Stack Overflow.
Go to Stack Overflow Found a bug or missing a feature?The AMP project strongly encourages your participation and contributions! We hope you'll become an ongoing participant in our open source community but we also welcome one-off contributions for the issues you're particularly passionate about.
Go to GitHub