Animations with JavaScript functions

— An article about: - Animations - JS

This all started when I was looking to add scroll based animations to the home page of this portfolio. I set out to find a library to help a bit with that. There’s quite a few in the wild. Time-based animations libraries that I could then tie to the scroll position (like greensock, anime.js, velocity or tweenjs). Or more scroll specific things (like scrollmagic).

While they all seemed to do a pretty good job (a lot of websites use them in production), they all had one major flaw to me. They’re all quite monolithic. They provide plenty, and your users download all that plenty, whether your website uses 1% or 99% of their features.

I used this as an excuse to explore how animations could be expressed through functions, rather than OOP APIs. Looking to compose just the features that the animations needed to limit what visitors would have to download. Let’s see how it went!

A simple starting point

Before diving into complex animations driven by scroll, let’s start with a more restricted case: a simple time driven fade-in. Written in plain JS, this goes like this:

Definitely smaller than embedding a library. But while it’s nice to know how to write it all from scratch by hand, a bit of abstraction would help to reuse things from one animation to another.

Divide and conquer

The code above mixes two main parts of the animation:
– generating some measure of progress (here using requestAnimationFrame ticks)
– interpolating this progress into updates of the UI (here with target.style.opacity)

So let’s split things up accordingly.

That’s a first step! We can use our timer to power all kinds of animations. And control the fadeIn from other sources of progress… the scroll position maybe.

Progress on scroll

A time-based source of progress works like this: “run for N ms (after a delay of D ms maybe)”. In the same spirit, a scroll based source of progress would go “run for N% of the scroll (after a delay of D% maybe)”. Pixels would work too, but given the diversity of screen heights around… best use percents.

So let’s create just that (ignoring for now that the viewportHeight might change when resizing the browser):

Going further

This is just a simple base to start with. From there, there’s plenty more to explore, keeping this idea of composing functions to create animations. While creating this portfolio, I touched on:

And other topics come to mind too:

I’ve started to gather some code on the tinymation project on Github. If you have thoughts on the topic, maybe specific use case, I’d be really happy to head about them. Feel free to look at the code and add issues (or comment on the existing ones).