Menu Home

WebAnimation

Hi everyone, and welcome to another exciting edition of Boring JavaScript! Today, we tackle WebAnimation, which is a convenient and easy way to build CSS animations with your DOM elements in JavaScript, thereby making them dynamic!

Don’t like to read? Then watch the video.

Walt Would Have Been Proud

Let’s take a look at a simple CSS animation that moves a DOM object by changing the ‘margin-left’ setting from 0 to 40rem in 3 seconds:

#cat.move-me {
    animation: moveTheCat 3s linear;
    animation-fill-mode: forwards;
}

@keyframes moveTheCat {
    0% {
        margin-left: 0;
    }
    100% {
        margin-left: 40rem;
    }
}

Whenever the ‘move-me’ class is applied to the ‘#cat’ DOM element, CSS will animate the element by increasing the ‘margin-left’ value from 0 to 40rem over a period of 3 seconds. After that time, the animation will stop and the last value of 40rem will remain – that is controlled by the ‘animation-fill-mode’ setting above.

All we need to do in our JavaScript is apply the class when a button is clicked:

const go = document.getElementById('go');
const cat = document.getElementById('cat');

const moveTheCat = () => {
	cat.classList.add('move-me');
};

go.addEventListener('click', moveTheCat);

And that’s it – literally.

But there’s a problem. What if you wanted to change the speed of the cat dynamically? Well – you can’t just using CSS. That value is hard-coded and cannot dynamically be changed (well, actually, you can through CSS variables and changing those through JavaScript, but it’s not intuitive and it looks messy).

WebAnimation is your answer.

Gertie To the Rescue

WebAnimation is simply a JavaScript way of representing CSS animations using JavaScript. In addition to being able to animate anything CSS can, you can also play, pause, and reset the animation that is in progress.

In our case, we’re going to do a straight translation of our CSS code, and show you how easy it is.

Let’s look at the KeyFrames first:

const keyFrames = [
	{ marginLeft: 0, offset: 0 },
	{ marginLeft: '40rem', offset: 1 }
]

/* replaces the following CSS code:
@keyframes moveTheCat {
    0% {
        margin-left: 0;
    }
    100% {
        margin-left: 40rem;
    }
}
*/

Notice that the CSS keyframes resembles an array, so it makes sense that we create an array to represent our keyframes. The contents are easy to understand, but I want to cover one part in a little more detail.

The ‘offset’ property represents the percentage that you see in the CSS keyframes. But this is optional. WebAnimation will automatically split up the entries in the array evenly, so if you have 5 keyframes, and you do not specify an offset, the values assigned to each entry in the array will be 0, .25, .5, .75, and 1. The first entry always gets the value of 0, and the last entry always gets the value of 1.

This means that you will always need at least 2 keyframe entries in your array.

This also means that I didn’t need to specify ‘offset: 0’ and ‘offset: 1’. I only did it so I could explain what it does.

Next, we process the animation part of the CSS itself:

const timing = {
	duration: 3000,
	easing: 'linear',
	fill: 'forwards'
}

/* replaces the following CSS
#cat.move-me {
    animation: moveTheCat 3s linear;
    animation-fill-mode: forwards;
}

This one is also simple, although some of the property names have changed (MDN has great articles on all of these). One thing to note is that ‘duration’ is in milliseconds, and CSS specifies the duration in seconds. Just remember that!

Putting it all together

We have the keyframes and the timing defined – let’s change our JavaScript code to animate it!

const go = document.getElementById('go');
const cat = document.getElementById('cat');

let catAnimation;

const keyFrames = [
	{ marginLeft: 0, offset: 0 },
	{ marginLeft: '40rem', offset: 1 }
]

const timing = {
	duration: 3000,
	easing: 'linear',
	fill: 'forwards'
}

const moveTheCat = () => {
	catAnimation = cat.animate(keyFrames, timing);
};

go.addEventListener('click', moveTheCat);

The big change is in the ‘moveTheCat’ function. Instead of applying a class to the DOM element, we now use the ‘animate()’ method, passing it two arguments: the Keyframes and the timing. JavaScript takes care of everything else for you.

And if you wanted to change the duration (which we couldn’t do with CSS)? Simple!

const go = document.getElementById('go');
const cat = document.getElementById('cat');
const range = document.getElementById('range');
const rangeValue = document.getElementById('range-value');

let catAnimation;

const keyFrames = [
	{ marginLeft: 0, offset: 0 },
	{ marginLeft: '40rem', offset: 1 }
]

const timing = {
	duration: 3000,
	easing: 'linear',
	fill: 'forwards'
}

const moveTheCat = () => {
	catAnimation = cat.animate(keyFrames, timing);
};

const changeTheValue = () => {
	rangeValue.textContent = range.value;
	timing.duration = parseFloat(range.value) * 1000;
}

go.addEventListener('click', moveTheCat);
range.addEventListener('input', changeTheValue);

There is now an <input type=”range”> element on the web page that, when it changes (Line 29), it calls the ‘changeTheValue’ function which changes the ‘duration’ value in the timing.

And the next time the ‘Go’ button is pressed? The animation has changed speed!

The Video

Want to see it in action? Check out our video!

Shameless Plugs

Check out all our videos at: https://www.boringjavascript.com

Github Repository: https://github.com/TheVirtuoid/boringjavascript

Check out everything at: https://www.thevirtuoid.com

Facebook: https://www.facebook.com/TheVirtuoid

Twitter: https://twitter.com/TheVirtuoid

YouTube: https://www.youtube.com/channel/UCKZ7CV6fI7xlh7zIE9TWqgw

Categories: Boring JavaScript Javascript

Tagged as:

thevirtuoid

Web Tinkerer. No, not like Tinkerbell.

Creator of the game Virtuoid. Boring JavaScript. Visit us at thevirtuoid.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: