June 22, 2020
I’ve been meaning to try out the Intersection Observer API for some time now. I seem to have an ever-growing list of third-party scroll libraries, and the prospect of replacing all these with a native browser API is extraordinarily tempting. The setup is straight-forward; essentially we are setting up a container within the viewport which watches specified elements for an intersection event. Here's one of a few videos which gives a great overview [link].
I was hoping to integrate this into a small visualisation within Codepen’s new Vue templates (nice to finally have, although debugging is a bit tricky still); however, I kept hitting roadblocks while trying to setup a simple example. As it turns out the Intersection Observer doesn't play nicely with Codepen or JSFiddle, as we're loading the whole thing into an iframe and typically our Intersection Observer targets the document root element.
So while the Intersection Observer is definitely promising, instead I opted for ScrollTrigger a recently released plugin from Greensock to manage the scroll animations. It's a very convenient syntax and we can configure options and add a Scrolltrigger to a full timeline like so:
// example.js
let tl = gsap.timeline({
scrollTrigger: {
trigger: ".container",
pin: true,
start: "top top",
end: "+=500",
scrub: 1,
}
});
tl.addLabel("start")
.from(".box p", {scale: 0.3, rotation:45, autoAlpha: 0})
There are a few features that really make this plugin stand out: pinning, scrubbing animations, tons of flexibilty with of state. Check out the docs here for a more detailed look at the features. And apart from the official docs here's another great intro video. One of my favourite features of this plugin are the visual markers. These allow us to easily see the start/stop of the element which is triggering (i.e. typically the viewport), and the start/stop of the element being triggered. Just set the markers property to True and here's what we get:
With the IntersectionObserver, when an intersection event is detected we have to manually loop through all the elements and filter out the ones which have the property “.isIntersected". It’s rather verbose and from a performance perspective we’re taking a hit, as the Observer is constantly watching all selected elements.
let observer = new IntersectionObserver(callback, options);
let callback = (entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
// do something interesting
}
});
};
I like to maximise the functionality of native browser APIs; however, the full feature set and easy integration with tweens makes GSAP’s ScrollTrigger an overwhelming win. I've put together a quick visualisation with some wikipedia data using ScrollTrigger which you can check out here.