When working on the new homepage for SamKnows.com, we decided to do something that none of us had ever seen before: create an animation that combined both time and the users position on the page to tell the story of SamKnows in an interactive, fun way. When researching how to develop this, I discovered that the technique is called "scrollytelling"*, and is a technique used mostly in journalism to tell a story. Unfortunately, most of the examples I found were quite laggy—especially on my 4K display—and didn't even attempt the animation on mobile.
* I think scrollytelling is a terrible name, and that we should all start calling it reactive storytelling.
This wasn't good enough for us.
I set out to create a library that could satisfy all the following:
- Combines a number of variables: in our case, scroll position, time, and user actions (such as clicking or arriving at a certain position on the page).
- Work with both SVGs and normal HTML elements.
- Produce a highly performant animation that works on any screen size.
- Work perfectly on a mobile device without lagging or using an excessive amount of battery.
As demonstrated by the completed home page, I succeeded! We've published it as an open source library on GitHub: samknows/transform-when.
So, let's take it for a spin.
Let's draw a circle to demonstrate when-scroll on (if you haven't already, scroll down).
#Animating on scroll
transform-when currently supports animating by three different variables: the users scroll position on the page (useful for parallax animations), time (useful for traditional animations) and user actions (such as clicking a button or the page load completing).
Let's look at animating on scroll, first. Let's change the colour of this circle and make it slightly smaller:
Neat. We changed the fill using CSS, and the scale using a transform.
#Animation through time
The second variable transform-when can animate by is time: this is provided using a variable called
i, which simply counts up one every frame (so, in a performant animation, about once every 16ms). If you want an actual time, you can do that yourself using
To demonstrate this, let's make the circle rotate. Wait, what? Okay, let's also turn it into a square so that we can see that it is rotating:
#Animation on user action
Finally, the third variable is "actions", generally triggered by the user. They're called by calling
transform.trigger('action-name', 1000) where
transform is the object returned by the transformer.
An action could be triggered by anything you choose. For examples, it could be the press of a button, it could be when a timer runs out, or it could be triggered when the user reaches a certain point on the page using a library like when-scroll.
To see an example of an action, click on the square or this link.
(When you scroll past this point, the animation might start to get a bit jerky: it's one of the share buttons or Disqus. Not sure why.)
transform-when can be used to power animations that take a number of variables—scroll position, time, and user actions—to produce an efficient, performant animation on both desktop and mobile devices.
You can find it on GitHub at samknows/transform-when and you can see an example of where we're using on the front page of SamKnows.com.
If you want to work on stuff like this, we're looking to hire a front-end developer right now! Drop me an email at firstname.lastname@example.org or find the job description on our careers site.