Animations with JS

Rate this content

Creating different animation effects like bouncing, typing with vanilla javascript. Looking at several approaches of creating animations with time based functions and Request Animation frame.

19 min
16 Jun, 2022

AI Generated Video Summary

Today's talk is about animations in Javascript, covering frame rates and different methods like CSS transitions and animations. JavaScript provides more control over animations, allowing interpolation and simulation of real-world scenarios. Different approaches to animating a box from zero to 100 pixels are discussed, including for loops, timers, and the web animations API. Request Animation Frame is highlighted as a solution for consistent and smooth animations. The Web Animations API is introduced as a powerful tool alongside CSS animations and transitions, although it has limited browser support.

1. Introduction to Animations in Javascript

Short description:

Today's talk is about animations in Javascript. We will discuss frame rates and how they affect animation smoothness. Different methods like CSS transitions and animations can be used to achieve web animations.

So how's everyone doing so far? Are you guys enjoying the talk? Nice. Any back end developers here? Making some noise? Any motion designers? Okay, nobody.

So today my topic is animations. Animations in simple word is just a way to communicate motion. So while this concept was introduced into movies first before it was brought into web, but people have been trying to find ways to communicate motion from a very long time. How many of you remember this flip book, where we would draw a bunch of drawings and flip them together really fast to create a perception of motion.

So the idea is that when images are shown fast enough, our brain loses the ability to see individual frames and blends them together into a single moving image. But in digital world, we have frames. Each frame has a drawing and the idea is similar to the flip book, it's just put those frames together really fast to create the perception of motion.

Hello, my name is Ashima. I'm a friend and engineer at Miro, and today I'm particularly going to be talking about animations in Javascript. So all of you must have heard this term, frame rates, frames per second. I first heard about it in movies. So frame rate is the number of frames shown in one second. So if we show 60 frames in one second, it becomes 60 frames per second, and more the frames we show in one second, the smoother the animation gets. In order to render smooth animations on web, we target 60 frames per second. But that depends a lot on the device which you are using. For instance, if you're using a mobile phone, there is a high likely chance that it's running on a frequency lower than 60 hertz. So the frame rate would be like 30 frames per second or whatever the device supports.

In web, we can achieve animations using JavaScript, using CSS, using CSS transitions and animations. In CSS transitions, you usually define two points. One is the starting point and the other one is the ending point. Whatever happens in between is controlled by the browser. So this is what we call interpolation. In CSS transitions, you usually need an action to trigger. So you would use a hover or a click. And you cannot run them in loop. So we have CSS animations. And in CSS animations, you can define intermediate points as well using key frames, apart from just defining the starting and ending point. And yes, the interpolation, again, is controlled by the browser.

2. Controlling Animations in JavaScript

Short description:

Sometimes CSS is not enough to achieve the desired animations in JavaScript. JavaScript provides more control over animations, allowing interpolation and simulation of real-world scenarios. There are different approaches to animating a box from zero to 100 pixels, including using a for loop, timers like set interval and set timeout, the requestAnimationFrame, and the modern web animations API. When using a for loop, the browser renders the box directly at 100 pixels instead of incrementally updating its position due to how the event loop works. Timers like set interval and set timeout can be used to solve this problem by executing a callback after a specified delay.

That's how it would move between different states. But sometimes it's not just possible to do everything with CSS. I know the browser does a lot for us when it comes to animations. But when we need more control over the animations, we need to use JavaScript. And so JavaScript allows you to control the interpolation and to simulate real world scenarios.

For instance, free falling of an object, or like falling of a snow. So let's suppose you are given this problem, that you want to animate a box from zero to 100 pixels. How many of you have encountered this in your interviews? I did. And I failed. But today we will see that there are a couple of, there can be a couple of approaches to solve this, basically. So you can use For Loop if you are new to JavaScript. You can use timers, set intervals, set timeout. You can also use the quest animation frame, and then the modern web animations API.

So if you're using For Loop, so you can run it from zero to 100 pixels, and tell your browser, okay, browser, render this to me at a particular position. But this does not work. What happens in this case is the box gets rendered directly at 100 pixels. But this is not what you want. You want to update the position incrementally. So the expectation is that browser would do something like this, like show it at 0, 1, 2, and then 100. But the reality is that the line gets executed, is translate X 100 pixels. Evil browser. So this is because how event loop works. I really like this diagram from Jake. If you haven't seen the talk, event loop, it's really a must-watch. So what is happening here is that the for loop gets executed as a task. And after the entire for loop gets executed, browser goes to calculate the styles, render the layout, and then do the paint. And that is why we see the translate x 100 pixels only getting executed.

Another way to solve this problem is using timers. You can use set interval and set timeout. Both of these function take a callback and a delay time after which the callback would be executed.

3. Controlling Animations in JavaScript (Part 2)

Short description:

To achieve a smooth animation, we need to target 60 frames per second. The delay time for set interval and set timeout should be around 16 milliseconds per frame. However, set interval does not guarantee the interval of execution if a function takes longer than the specified time. Set timeout can be used in recursion to ensure proper execution timing. Both timers have issues with inconsistent timing and lack of synchronization with the browser. Additionally, set interval continues running even if the tab is inactive, consuming more CPU and battery. To address these problems, we can use request animation frame.

So what should be the delay time here? Now definitely, you want to render the smooth animation. So for that, we discussed that we want to target 60 frames per second. So if 60 frames are to be rendered in 1,000 milliseconds, then one frame should be rendered in almost 16 milliseconds. So this is going to be the timer for the set interval as well as set timeout.

So here let's create a function like animate. And here you can use set interval. Inside set interval, you can update the position by 1. And of course, you don't want to have the interval running infinitely, so you can clear the interval when the box reaches 100 pixels. And after that, the browser will render it at the particular position. Now this works fine. If you run it, it perfectly runs a smooth animation. But the problem with set interval gets when the function inside set interval takes longer than the specified time. So let's suppose we had three functions here, right? And each one is to be executed at an interval of 16 milliseconds. But if the function 1 took longer than 16 milliseconds, let's suppose it took like 50 milliseconds, the rest of the two functions would be called instantly in an unexpected order. So set interval does not guarantee the interval of execution.

You can also approach this problem using set timeout. So here instead of running a loop inside, instead of using set interval, what you can do is use set timeout in recursion. So basically we are checking here if the position is less than 100, we will call the animate function again in the set timeout. So this works pretty well, and it also guarantees that our method gets fully executed until the function is running. The next function will never be sent for the execution. So the time difference between the execution of two functions is maintained. But there are still some problems with both the timers. So first of all, the delay, which is provided in the second argument, it can be longer than intended. So there can be inconsistent timing between the frames. Also these methods, they're not synced with the browser. So set interval, set timeout, they have no idea what else is going on the screen. So browser has to do the animation and then go back to paint the entire screen, which is a lot more computations. Also if you use set interval, then the animations, even if it is running in the background, the animations still keep on running even if the tab is inactive. So it's consuming more CPU and battery. To solve all these problems, there is request animation frame.

4. Request Animation Frame and Consistency

Short description:

Request animation frame syncs with the browser, automatically adjusts to the device refresh rate, and saves CPU usage and battery life. By incrementing the position based on time, animations can be consistent and smooth on all devices.

So anybody knows how many of you are familiar with it? Okay. Almost everyone has heard. So requestion animation frame tells the browser that you want to perform an animation. And ask the browser, can you do this animation for me when you go to render the screen, when you go to paint? Browser is like, yeah, sure. I will do this, I will run this function for you whenever I go to paint the next time.

So request animation frame takes a callback. As its execution is controlled by the browser, so there's no need to provide any timer, any delay time. So this is where request animation frame is in the event loop. So it's in some browsers, it's here, like, above the styles. But in some it's here. But the main idea is the function inside RAF gets executed when browser goes to paint the screen.

So the benefit is that it's synced with the browser. And also it gets automatically adjusted based on the device refresh rate. So if you are running these animations even in your mobile phone, the RAF would automatically get adjusted to the frame rate of the mobile phone. Also when the tab is inactive, the animations don't run. So it saves a lot of CPU usage and battery life. Now if we have to rewrite this function, using the animation frame, you can simply change the set timeout with the animation frame. And this would be like smooth animation. But can you see, there is still some problem.

So what is happening here right now is that this animation is running at different speed in different devices. Because the request animation frame would run at 60 frames per second in a browser. But in mobile phone, it would be capped at 30 frames per second. So in your browser, the animation is going to be two times faster. But you definitely don't want that. You want your animations to be consistent and smooth on all the devices. So here the idea is that instead of incrementing the position by one, what you can think of is that incrementing the position based on the time which has passed. So you can calculate here that what's the time has already passed and what should be the position of the box at that particular time. So we can pass a distance and a duration and increment the position based on the timing. Now this would run smooth on all the devices. So we have achieved a smooth and consistent animation on all the devices.

5. Optimizing Animations and Web Animations API

Short description:

To optimize animations further, offload calculations to a worker thread. Request Animation Frame is powerful but has drawbacks. Web Animations API is a powerful tool inspired by CSS animations and transitions.

But can you still optimize it further. If you see there are two things which we are doing here. We are doing the calculations and we are doing the drawing. And both of them are running on the main thread. So what is being done is that calculating position. The draw function, so right now what we want is to do the draw function in the request animation frame. So the responsibility of request animation frame should be only painting. And what you can do is offload the calculations to the worker.

So we all know that workers run in a parallel thread. So instead of doing the calculations inside the main thread, you can offload that to worker. So this is how our calculate position looks. It's simply we are doing the set interval. In set interval, you can update the position and clear the interval when box reaches the 100 pixels. So now instead of calculating the position, what you can do is offload it to the worker. So instead of calling calculate position, here you can call calculate position in the worker. And in the worker, you can do all the same calculations. So the worker will send to the main file that this is the updated position. So in the main.js, here you can get the updated position and this is how, so basically the solution would be. So now what you have done is that offloaded the calculations to worker. So our main thread is free to take any other user action.

So while the request animation frame is very powerful and it helps us achieve the smoother and performing animations. But there are still some drawbacks because request animation frame is running on main thread, right? And if the main thread is busy and the browser is taking longer time to paint the animations, then still we will have some struggle in having this smooth animations. It's like driving a Ferrari on Autobahn, but if you are stuck in a traffic jam, there is not much you can do. And also the request animation frame is capped at 60 frames per second in many Apple devices like iPad Pro. Although if you use CSS animations there, it can run at 120 frames per second.

So there's another very powerful tool we have, which is Web Animations API. So this is very much inspired from CSS animations and transitions. Also, syntactically, it's pretty similar to the CSS. But the problem with CSS is it's declarative. So whenever you are defining the keyframes, you have to specify all the values while you're writing the CSS.

6. JavaScript Animations and Web Animations API

Short description:

JavaScript allows dynamic values for positions and durations in animations. Web animations have a similar structure to CSS animations, with timing and animation models. The web animations API leverages the dynamic nature of JavaScript and is an additional tool alongside CSS transitions and animations. It runs on a composite thread, providing performant animations. However, support is limited to Chrome, Safari, and the latest version of Internet Explorer.

But with JavaScript, it allows you to dynamically set the values from positions to durations. So if you have to animate this box using CSS, you would write something like this. Define the duration, timing function, and define the keyframes. Web animations have the similar structure.

In web animations, you have the timing model and the animation model. In timing model, you would define durations, iterations, delay, easing. And in animation model, you would define the keyframes. So this is how it looks in the CSS. And if you are using web animations, then the keyframes would be inside an array. This object looks like a keyframe, apart from the fact that we are not defining the percentage here.

So the solution with the request animation frame sorry, web animations API would look something like this. So here you can leverage the dynamic nature of JavaScript. So what you can use is that distance and duration is passed into the function and you can dynamically set the distance. So I would say that we have many powerful tools to achieve animations on JavaScript. We have request animation frame. We also have CSS transitions and animations. And all of them are really powerful. And web animations is not something which is replacing them, but it's just an additional tool. So use whichever suits your requirement the best. Web animations API is also running on a composite thread, so it's not running on the main thread. That is why you are able to achieve very performant animations with web animations API. However, the support is still limited. It's in Chrome and latest version of Safari and Internet. But in the old browser, it's still not supported.

Thank you so much. And that's all we have in terms of JavaScript animations. I should get a seat in the front. That would be much better. So despite some technical issues, we managed. Yeah.


Q&A on Animations and Testing

Short description:

Congratulations on the wonderful talk. If you have any questions, please ask using Slido. The animations can be shared later, and a link can be found on the speaker's Twitter handle. Testing animations can be challenging, but using customization and libraries can help. CSS animations are preferable for simple animations, while JavaScript animations offer more control and interpolation.

Congratulations. That was a wonderful talk. I'm wondering, just because we don't have a question right now, which is why this slide is up. People, please ask your questions using Slido.

I wonder, do you have a portfolio site somewhere where we can see the animations you've made? The animations, I don't have it uploaded to GitHub at this moment. But yeah, so I can share them later. Yeah, that'd be awesome. I think everybody has seen your Twitter handle, so you can share the link there. Yeah, sure, sure. That'd be really fun.

One question I will take is how do you test with animations? We're used to simply turning them off in tests, but that introduces bugs in our animations and they go unnoticed, right? Yeah, so that depends on what kind of approach you are using. If you are using setInterval or you are using with the requestAnimationFrame. I know there are a couple of problems with the testing framework, and since we are using the timers it's also difficult to test it. But so far what I do is I use some customization, some libraries to do the testing. Cool, thank you so much.

Oh, we have one more question coming in. Like, just in time. In which scenarios do you reach for CSS animations, and in which should you use JavaScript animations instead? So, if you are, you know that the animations is going to be simple and you don't want much control over the animations, always prefer CSS animations. Because it's more performant. But if you need more control, like I told the interpolation, if you want to control those values as well, that you cannot define it on the, with CSS keyframes, then it's better to go with the JavaScript. Awesome. Thank you so much, and thank you so much again for your talk. Thank you.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

JSNation Live 2021JSNation Live 2021
33 min
Keep Scrolling
Wait! Not so fast - Stop scrolling and hang out with me for a while! When done right, scroll based animations can add polish to a site, and make online storytelling feel more immersive. GreenSock's ScrollTrigger enables you to achieve buttery smooth scroll based animations with minimal code. Let's dig in to some of it's features together.
Vue.js London Live 2021Vue.js London Live 2021
32 min
Animation and Vue.js
There's a lot to gain from adding animations to your site or app. Beyond their visual appeal, you can guide the user's attention, cover up slow to load components and elements, and reveal sections of a page without the user wondering where it came from. This talk will cover the built-in ways Vue.js helps you animate your site, and how for more complicated animations you can hook into third party libraries. It'll also cover the basics of animation itself – what to animate, what not to animate – and how you can use animations to enhance your website without harming the experience of people with disabilities.
React Summit Remote Edition 2021React Summit Remote Edition 2021
35 min
Lessons Learnt from Building Interactive React Applications
When users directly manipulate onscreen objects instead of using separate controls to manipulate them, they’re more engaged and more readily understand the results of their actions. Subtle animations can give people meaningful feedback to help clarify the result of their actions. But, the devil is in the details. What often seems simple can be complex to get right, especially when you care about accessibility. Sid shares the lessons he has learned building interactive UIs.

Workshops on related topic

JS GameDev Summit 2022JS GameDev Summit 2022
165 min
How to make amazing generative art with simple JavaScript code
Instead of manually drawing each image like traditional art, generative artists write programs that are capable of producing a variety of results. In this workshop you will learn how to create incredible generative art using only a web browser and text editor. Starting with basic concepts and building towards advanced theory, we will cover everything you need to know.