Scroll-Linked Animations With the Internet Animations API (WAAPI) and ScrollTimeline

No Comments

The Scroll-linked Animations specification is an upcoming and experimental addition that permits us to hyperlink animation-progress to scroll-progress: as you scroll up and down a scroll container, a linked animation additionally advances or rewinds accordingly.

We coated some use instances in a earlier piece right here on CSS-Tips, all pushed by the CSS @scroll-timeline at-rule and animation-timeline property the specification offers — sure, that’s appropriate: all these use instances had been constructed utilizing solely HTML and CSS. No JavaScript.

Other than the CSS interface we get with the Scroll-linked Animations specification, it additionally describes a JavaScript interface to implement scroll-linked animations. Let’s check out the ScrollTimeline class and tips on how to use it with the Internet Animations API.

Internet Animations API: A fast recap

The Internet Animations API (WAAPI) has been coated right here on CSS-Tips earlier than. As a small recap, the API lets us assemble animations and management their playback with JavaScript.

Take the next CSS animation, for instance, the place a bar sits on the prime of the web page, and:

animates from pink to darkred, thenanimates from zero width to full-width (by scaling the x-axis).

CodePen Embed Fallback

Translating the CSS animation to its WAAPI counterpart, the code turns into this:

new Animation(
new KeyframeEffect(
doc.querySelector(‘.progressbar’),
{
backgroundColor: [‘red’, ‘darkred’],
rework: [‘scaleX(0)’, ‘scaleX(1)’],
},
{
length: 2500,
fill: ‘forwards’,
easing: ‘linear’,
}
)
).play();

CodePen Embed Fallback

Or alternatively, utilizing a shorter syntax with Factor.animate():

doc.querySelector(‘.progressbar’).animate(
{
backgroundColor: [‘red’, ‘darkred’],
rework: [‘scaleX(0)’, ‘scaleX(1)’],
},
{
length: 2500,
fill: ‘forwards’,
easing: ‘linear’,
}
);

CodePen Embed Fallback

In these final two JavaScript examples, we will distinguish two issues. First, a keyframes object that describes which properties to animate:

{
backgroundColor: [‘red’, ‘darkred’],
rework: [‘scaleX(0)’, ‘scaleX(1)’],
}

Second is an choices Object that configures the animation length, easing, and so on.:

{
length: 2500,
fill: ‘forwards’,
easing: ‘linear’,
}

Creating and attaching a scroll timeline

To have our animation be pushed by scroll — as a substitute of the monotonic tick of a clock — we will maintain our current WAAPI code, however want to increase it by attaching a ScrollTimeline occasion to it.

This ScrollTimeline class permits us to explain an AnimationTimeline whose time values are decided not by wall-clock time, however by the scrolling progress in a scroll container. It may be configured with a number of choices:

supply: The scrollable aspect whose scrolling triggers the activation and drives the progress of the timeline. By default, that is doc.scrollingElement (i.e. the scroll container that scrolls the complete doc).orientation: Determines the course of scrolling, which triggers the activation and drives the progress of the timeline. By default, that is vertical (or block as a logical worth).scrollOffsets: These decide the efficient scroll offsets, transferring within the course specified by the orientation worth. They represent equally-distanced in progress intervals during which the timeline is lively.

These choices get handed into the constructor. For instance:

const myScrollTimeline = new ScrollTimeline({
supply: doc.scrollingElement,
orientation: ‘block’,
scrollOffsets: [
new CSSUnitValue(0, ‘percent’),
new CSSUnitValue(100, ‘percent’),
],
});

It’s not a coincidence that these choices are precisely the identical as the CSS @scroll-timeline descriptors. Each approaches allow you to obtain the identical end result with the one distinction being the language you utilize to outline them.

To connect our newly-created ScrollTimeline occasion to an animation, we move it because the second argument into the Animation constructor:

new Animation(
new KeyframeEffect(
doc.querySelector(‘#progress’),
{ rework: [‘scaleX(0)’, ‘scaleX(1)’], },
{ length: 1, fill: ‘forwards’ }
),
myScrollTimeline
).play();

CodePen Embed Fallback

When utilizing the Factor.animate() syntax, set it because the timeline choice within the choices object:

doc.querySelector(“#progress”).animate(
{
rework: [“scaleX(0)”, “scaleX(1)”]
},
{
length: 1,
fill: “forwards”,
timeline: myScrollTimeline
}
);

CodePen Embed Fallback

With this code in place, the animation is pushed by our ScrollTimeline occasion as a substitute of the default DocumentTimeline.

The present experimental implementation in Chromium makes use of scrollSource as a substitute of supply. That’s the rationale you see each supply and scrollSource within the code examples.

A phrase on browser compatibility

On the time of writing, solely Chromium browsers assist the ScrollTimeline class, behind a characteristic flag. Fortunately there’s the Scroll-Timeline Polyfill by Robert Flack that we will use to fill the unsupported gaps in all different browsers. Actually, the entire demos embedded on this article embody it.

The polyfill is offered as a module and registers itself if no assist is detected. To incorporate it, add the next import assertion to your JavaScript code:

import ‘https://flackr.github.io/scroll-timeline/dist/scroll-timeline.js’;

The polyfill additionally registers the required CSS Typed Object Mannequin courses, ought to the browser not assist it. (👀 Taking a look at you, Safari.)

Superior scroll timelines

Other than absolute offsets, scroll-linked animations can even work with element-based offsets:

With the sort of Scroll Offsets the animation relies on the placement of a component throughout the scroll-container.

Usually that is used to animate a component because it comes into the scrollport till it has left the scrollport; e.g. whereas it’s intersecting.

A component-based offset consists of three components that describe it:

goal: The tracked DOM aspect.edge: That is what the ScrollTimeline’s supply watches for the goal to cross.threshold: A quantity starting from 0.0 to 1.0 that signifies how a lot of the goal is seen within the scroll port on the edge. (You would possibly know this from IntersectionObserver.)

Right here’s a visualization:

CodePen Embed Fallback

If you wish to know extra about element-based offsets, together with how they work, and examples of generally used offsets, take a look at this text.

Factor-based offsets are additionally supported by the JS ScrollTimeline interface. To outline one, use a daily object:

{
goal: doc.querySelector(‘#targetEl’),
edge: ‘finish’,
threshold: 0.5,
}

Usually, you move two of those objects into the scrollOffsets property.

const $picture = doc.querySelector(‘#myImage’);

$picture.animate(
{
opacity: [0, 1],
clipPath: [‘inset(45% 20% 45% 20%)’, ‘inset(0% 0% 0% 0%)’],
},
{
length: 1,
fill: “each”,
timeline: new ScrollTimeline({
scrollSource: doc.scrollingElement,
timeRange: 1,
fill: “each”,
scrollOffsets: [
{ target: $image, edge: ‘end’, threshold: 0.5 },
{ target: $image, edge: ‘end’, threshold: 1 },
],
}),
}
);

This code is used within the following demo beneath. It’s a JavaScript-remake of the impact I coated final time: as a picture scrolls into the viewport, it fades-in and turns into unmasked.

CodePen Embed Fallback

Extra examples

Listed below are a number of extra examples I cooked up.

Horizontal scroll part

That is primarily based on a demo by Cameron Knight, which incorporates a horizontal scroll part. It behaves equally, however makes use of ScrollTimeline as a substitute of GSAP’s ScrollTrigger.

CodePen Embed Fallback

For extra on how this code works and to see a pure CSS model, please seek advice from this write-up.

CoverFlow

Keep in mind CoverFlow from iTunes? Nicely, right here’s a model constructed with ScrollTimeline:

CodePen Embed Fallback

This demo doesn’t behave 100% as anticipated in Chromium resulting from a bug. The issue is that the beginning and finish positions are incorrectly calculated. Yow will discover a proof (with movies) in this Twitter thread.

Extra data on this demo will be discovered on this article.

CSS or JavaScript?

There’s no actual distinction utilizing both CSS or JavaScript for the Scroll-linked Animations, aside from the language used: each use the identical ideas and constructs. Within the true spirit of progressive enhancement, I might seize to CSS for these form of results.

Nonetheless, as we coated earlier, assist for the CSS-based implementation is pretty poor on the time of writing:

Chromium helps it behind a characteristic flag.Firefox is making ready some work for it. (Mozilla Ticket #1676780)No phrase from Safari simply but. (WebKit Ticket #222295)

Due to that poor assist, you’ll definitely get additional with JavaScript at this very second. Simply be sure your web site will also be seen and consumed when JavaScript is disabled. 😉

The submit Scroll-Linked Animations With the Internet Animations API (WAAPI) and ScrollTimeline appeared first on CSS-Tips. You’ll be able to assist CSS-Tips by being an MVP Supporter.

    About Marketing Solution Australia

    We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

    Request a free quote

    We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

    Subscribe to our newsletter!

    More from our blog

    See all posts

    Leave a Comment