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.
Animation and Vue.js
AI Generated Video Summary
1. Introduction to Animation in Vue JS App
Today, I'm going to be talking about animation in your Vue JS app. How you can use animation to improve your app, why you should do it, and when you maybe shouldn't be animating your app. Animations are a good way of guiding attention or distracting users. If you add too much animations to your site, they will be totally unusable. No one will be able to make it through your text.
Today, I'm going to be talking about animation in your Vue JS app. How you can use animation to improve your app, why you should do it, and when you maybe shouldn't be animating your app.
My name is Callum. I'm a creator developer based in London. I've written a book called Vue JS Up & Running published by O'Reilly Media. If you're on Twitter, that's my handle, feel free to give me a follow.
So, I figured we'd jump straight in with the why. Why would you want to add animations to your site? So, beyond the obvious visual appeal, like animations look good. That's a valid reason to add animations. There are a few functional reasons that you might want to add animations to your site. So, animations are a really good way of leading users around your app. So, for example, you might have a call to action you want them to look at, or you might want them to go to the next page. They might have made a mistake on a form and you want to alert them to it. Animations would help in these scenarios, by guiding the user's attention towards this part of the page.
So, as I just mentioned, animations are a good way of guiding attention or distracting users. So, another case would be you've got a page that's loading quite slowly. If you display a loading sign or some sort of animation, the user will perceive the page to have maybe loaded a bit quicker. But of course too much distraction is very much a bad thing. If you add too much animations to your site, they will be totally unusable. No one will be able to make it through your text. And this is especially bad for people with some disabilities, such as people with ADHD or people with some vestibular disorders who will be really badly affected by too much animation. So you've got to keep an eye out for that.
So I figured we could make most of this talk just a big demo. I'm not so big on slides, even though they look like slides. So here is our first thing. It's just on this page, it's this menu here. So I'm sure if you've been on the internet before, which I figure you have, especially if you're watching this streamed, you'll have seen this kind of menu before. You click on a button and menu comes in from the side. And this is a thing, this is probably one of the animations I've implemented most commonly in VGS apps. So let's have a look at the code which powers this.
2. Animation in Vue JS App
We've got our menu open state, which is either true or false. This is our menu, which we're using the vshow directive. The transition component adds classes to the menu element for CSS transitions. The menu is initially off-screen and translated in from the right when added to the DOM. The CSS transition property is used to animate the transform property, taking 0.3 seconds and using easing. The leave class has a different animation. The menu moves slowly and then speeds up when it goes out.
Here I'll just talk you through it briefly. We've got our menu open state, which is either true or false. Then here, this is our menu, which we're using the vshow directive so that when the ref is true, then the menu is open, otherwise it's not added to the DOM.
And you'll see we've got this transition component wrapped around it. So what this does is this is a built-in component in Vue. This means that when the state changes, when the menu open changes from false to true, it isn't just added to the DOM, it is added to the DOM, but it's got a bunch of classes added to it, which you can use to, in this case, add a CSS transition even.
So here, what we can see is this class is, so when this element is added to the DOM, it's added with this enter from class. So it's got a CSS transform, which translates it to the right by 100%, which in this case would be the width of the menu. So effectively, when it's just added to the screen, the menu is just off screen here. So, you can imagine it's sat slightly off screen. You press the button, it comes in on screen. That's what this translate means, translate x 100%, translate it in the x direction, 100%, which in this case is 100% of the width of this.
So, the next thing Vue does once it's added this class and added this element into the DOM, is it adds this class called interactive, which we used to add a transition, which we use a CSS transition, and then it removes this class so the new transform will be unset, so effectively, it will be translated nowhere. So it will be its natural position in the DOM, which is here. So what the CSS transition property does is, in this case, we're saying transition the transform property, take 0.3 seconds to do it and use this easing. I'll get back to easing in a second. But effectively, what this does is you can give it quite a few CSS properties, and it means that when it changes, don't change it immediately, transition it from the old value to the new value in this time. So in this case, we're saying we want our CSS transform, which is going from translation to the right to nothing, because the class is being removed, and taking 0.3 seconds to do it. So the explanation is a little convoluted. But hopefully in the context of seeing what the menu does, that makes sense. That's the enter class. We've got a slightly different class for leave. So you can just combine these into one depending on what you want to do. So you'll see on some of my later examples, I'll have enter active, and leave active in the same rule. And then I'll just have this, the transform and 0.3 seconds. In this case though, we have some easings. So we've got ease out on the way in, and ease in on the way out. And that won't make sense if you don't know what it means. So I will show you. So if you watch this menu come in and out, you'll see when it goes out, it starts off moving slowly, and then it speeds up.
3. Understanding Easings in Animation
You can see that when using ease out and ease in, the animation starts moving quickly and then slows down towards the end. This effect is achieved by using different easings, which can be found on MDN and the gsat website. These resources provide explanations and charts to help you understand easings.
You can sort of see it. And then on the way in, it does the opposite. It starts moving quickly, and then it slows down towards the end. You see that? So that's what this ease out and ease in means. Ease out means we're using an easing which, it doesn't just translate from this position to this position linearly like that, and then stopping straight. It means it slows down. So it starts off fast, and then it slows down. There's a bunch of different easings available. MDN has a page that explains them all, and some charts. The gsat website, which we'll talk about later, has a bunch of animated charts which are also really useful for understanding easings.
4. CSS Animations and Keyframes
So here's our CSS animation. We're using a CSS animation instead of a transition. The animation property lets you set up keyframes to define the animation states. For example, at 0% opacity is set to 0, making the text transparent. At 50%, opacity is set to 1, making the text fully visible. We also have a more complicated transform, including translation, scaling, and rotation.
So here's our CSS animation. So again for this, we're using our transition component. It's fairly similar to how the last one works. Instead of a menu button, we've got an active... We've got a separate button in the DOM which we're using to animate it instead of the menu button. But it's still the same idea. We've got something that's just true or false and we're using Vshow here.
The main difference here is that we're using a CSS animation instead of a transition. So you'll see here we've got the animation property instead of the transition property, although we're using the same classes mostly. What this does is a CSS animation, instead of just saying you've got one transition which goes from one place to another, it lets you set up keyframes. So you're saying what you want to happen at each state of the animation. So you're saying you want the animation... With 0% you're saying the animation to start here, 50% of the time the animation has completed you want this. And then 100% is where you want it to end up.
So here we've got... If we start by looking at the opacity, so the animation takes 0.7 seconds. What we've got here is at 0 seconds, so just after you've clicked the button, it's opacity 0. So you won't be able to see the text, it will be completely transparent. And then because it's 0.7 seconds, at 50% of that is 0.35 seconds, the opacity is set to one. So it's fully visible halfway through the animation, which we wouldn't be able to do without with the CSS transition, because you can only have... Effectively, you could only set 0% and 100%. You can't set the middle bits.
Further to that, we've got a more complicated transform. So on the last slide, on the last demo, we had a translate transform. But this one, we're also adding scaling and rotation, which are two other properties supported by transform. So in this one, we're at 0%, we're starting translated up and left a bit. And then very small scaled right down.
5. Animating Objects and Performance
So scaled means making an object smaller, and rotate is rotation. We're rotating it to the left by three degrees. Then halfway through the animation, it's transformed to go down and to the right, slightly bigger, and rotated in the opposite direction. Skew is a property that moves one side of a rectangle, making it skewed. When animating, only transforms and opacity can be performance animated, as they don't trigger a repaint. Other properties like height and color can be animated but may not perform well. Transform and opacity are hardware accelerated and more performant. However, be cautious as animating other properties may impact performance.
So scaled means taking an object like that, and you're making it smaller. And rotate is rotation. So we're rotating it minus three degrees to the left. Then halfway through the animation, we've got a separate transform, it's going down to the right of where it'll end up. It's going slightly bigger, and it's being rotated in the opposite direction. And then at the end, we're just setting it back to what it should be normally. So when this animation is removed, it'll look as it should, there'll be no jumps. So that's what that looks like.
We can see it's starting about here, it's jumping down here, then come back to here, and it's fading out in the first half of the animation. When it's halfway through the animation, it's fully visible. In addition to translate, scale, and rotate, there's also a further property called skew, which, if you can imagine a rectangle, like that, skew slightly makes... It moves one of the sides, so it's like one of the top of the bottom, so it's like that, it makes it skewed. I've actually never used that.
Yes, I figured now we've got this open, this would be a good time to talk about performance, so maybe you haven't seen this before, and you're thinking, wow, I can now animate everything. I can animate height. I can animate color. So in theory, yes, you can animate height. You can animate color. Some of the demos later on I will be animating color, but they aren't performance to animate. The only things you can performance animate are transforms and opacity. So the reason for this is they're the only things that don't trigger a repaint. So if we take the menu we looked at on the last example, so it's coming in from the right of the screen. You might think we can absolutely position the menu and then we can animate the right property. I mean you can do that but it won't animate at 60 frames per second, it'll look jerky, it won't look great. Because every time, every frame once the right property changes a bit the browser has to look at everything else on the page or everything nearby to figure out if that has moved as a result. Whereas with transform with opacity it doesn't have to look at any other elements. So these can be hardware accelerated, they're a lot more performant than anything else. I mean you can use other things. Try to use these where you can but sometimes you'll want to animate some stuff which these just can't animate. But be aware that it might hurt performance.
6. VShow versus Vif
VShow and Vif are directives that show and hide elements. VShow hides the element with display none, while Vif removes it entirely from the DOM. Use VShow when an element is being removed and added multiple times, and Vif when an element is only coming in once and won't be seen again.
Also I've been using VShow mostly. I figured now's a good time to talk about Vif versus VShow. So both are directives that show and hide an element. So you change it to Vif and it would look exactly the same. The difference between VShow and Vif is that for VShow the text is still in the DOM. It's just hidden with display none. Versus with Vif it would be removed from the DOM entirely. So if something's being removed and added again multiple times, you generally want to use VShow. Well if something's just coming in once and then it's never going to be seen again, that's where Vif is beneficial. I mean in this context, because it's not being added and removed that often, it probably doesn't matter that much. But if you can imagine, say you've got a large component with a YouTube iframe nested inside it. You don't want to be adding and removing that from the DOM repeatedly.
If we look at the code for this one, you can see there's a bit more code. Bear with me. For this one, we're importing a library called GSAP, which stands for the GreenSock animation platform. It's a very heavily used library. Lots of websites use it. I use it a lot as part of my job. It's a good library. It's good fun. And it works well with Vue. There are other libraries, like animajs, available. There's loads of animation libraries. You don't have to use this one. So, you can see here we're still using our transition component. We've used this for the first three examples.
8. Listening to Events and Chaining Animations
In this case, we're listening to two events: Enter and Leave. Each event calls a different handler function. We set up a GSAP timeline to chain multiple animations together. The background element moves independently of the actual element, and the heading and text elements come in one after the other. The animation takes the element from Y equals 50 and opacity zero to Y equals zero and opacity one, using GSAP's automatic resolution of the Y property to transforms.
But in this case, we're listening to two events. We're listening to the Enter event and we're listening to the Leave event. And they both call different handlers. So, if we take the Enter event, it calls the handleEnter function, which is up here. So, it's passing two arguments. The first one is the element. So, it's this element. I will come back to the other argument in a minute.
And what we're doing here is we're setting up a Gsap timeline. A GSAP timeline is a way of chaining multiple animations together. So, in this case, we've got our background element. We've got a separate element for the background because it moves independently of the actual element. So, you'll notice if I show and hide it, it goes outside of the actual element. So, that's why we've got a separate background element. And we've got our heading and our text. And they're all coming in one after the other, which is what GSAP timelines are really good for.
So, this is a little outside the scope of this talk, so I won't go into it too much. But I'll just explain briefly what this is doing. So, this is animating. It's taking this element. It's animating it from Y equals 50, opacity zero. So, down slightly and transparent. And it's animating it to Y equals zero. It's original position, and opacity one. And taking 0.9 seconds to do it. You might have noticed in the previous example, I said to always animate translation, not any other form of moving an element. And this has got this Y property. GSAP automatically resolves that to transforms. It's a nice way of working. Instead of having to have a transform here and like calculate it as a string, that wouldn't be very fun.
9. Animation Syntax and List Animations
And then we've got this syntax here. So this is all fairly similar stuff. Then we've got this which says we want this animation to start 0.2 seconds after the previous one. And we want this one to start 0.1 seconds after this one. And we've got something kind of similar on the way out. But I won't talk it through.
So the next thing we'll look at is it's very similar to this example. It's. You'll notice as I've loaded the page, it wasn't here. And I had to press the button to get it coming. If I had if this was set to true already, it wouldn't have animated and it would have just been there already. It wouldn't have animated. So we've also got another property called appear. So let's look at that so we can set we can add appear to be here. And if you set this to try, what it will do is when we navigate to the page or we relate the page, it'll animate. And so I'll just refresh the page that you can see it's animated and pretty simple to be. But it's it's it's a good way of getting animations. When you first like the page.
So next, so everything so far has been looking at single elements or. I mean, this isn't a single element. This is three elements, but it's one child of the transition component. Next, let's look at list animations. So in this case, we've got multiple elements.
10. Handling Multiple Elements with Transition Group
When typing in the input field, the text is displayed as separate letters using span elements. The computed property splits the text into an array of letters, which are then iterated and added to the DOM one letter at a time. To handle multiple elements in the DOM, a transition group component is used. CSS animations are applied using the all property to transition everything that changes. When adding or removing letters, the other letters slide to the new position instead of jumping, thanks to Vue's automatic handling of the move class.
I'll just type in so I'll show you what this code does. So what's going on here is when I type in here, it displays it as it splits up into separate letters and displays it as span elements. So you can see here's our text that we're typing into from the input. And then we've got a computed property, which splits it across, splits it apart by letters and returns it as an array, which we're then iterating through to. Yeah, we're iterating through it and putting it in the DOM one letter at a time.
So in our transition group. Well, it might not be obvious looking at it because it's only one element written here. But it does work out as multiple elements in the DOM, one for each letter. So for this, we can't use our old transition component. It'll complain at us. It won't work. But instead, we've got a transition group component and also built into Vue, which is really good for handling groups of elements. So here we're using CSS animations. We're back to using CSS animations. And what this example here does, it's fairly similar to the animation example. You can see when it enters and when it leaves, we add a transition. Here we're saying we're using the all property, which instead of saying transform 0.4 seconds, comma opacity 0.4 seconds, we're saying we want to animate everything, we want to transition everything that changes. And here you can see that we're animating it from and to opacity 0 and then we're translating it down 30 pixels. So let's look at the example again. If I remove one, it fades out and moves down. And if I add one, the opposite.
Now this is all right, but you can see you might have noticed that when we delete a letter, it moves down and then when it's removed from the DOM, the other letters jump. Or in the opposite direction, when we add one, it jumps. The other letters jump when we add a new one to the DOM. Luckily, Vue has a way of working with this, which I'll show you in the next demo. So here you can see when I add the new letter, the other letters slide to the new position instead of jumping. And to do that, it's pretty simple. I'll talk about the rest in a second. It's just adding a move class and Vue automatically sees that you're doing something with that. And handles the position or change automatically.
11. Different Kinds of Movements and State Transitions
I also had to add this. It was buggy without it. There's other kinds of movements. For example, this is an anagram generator. When I press enter, it shuffles the letters. The complication is the keys. Most of the code handles this. The final animation we'll look at is state transitions.
I also had to add this. I don't know why. It was buggy without it. I couldn't find it in the documentation. Maybe it's a bug. I don't know.
So yeah, this is moving. But there's other kinds of movements. So, for example, let's, this is some sort of anagram generator, I guess. So, if I press enter, it shuffles all the letters to a different position. And because we're using the move class, Vue is automatically moving it around for us. It's really nice. Yeah.
So, one thing to note, so, you might have noticed there's quite a lot of code when I showed this before. And this is because it's two states. I've got this text in the right order and I've got it in the wrong order. So, the complication here is the keys. If I just used the order here, so, if I used 0, 1, 2, 3, 4 as the keys, then this wouldn't animate because you wouldn't be able to tell that I've shuffled them. It would just think I've changed what letter is in them. So, most of the code here is handling that. So, the split text is adding the index and then we've got a new shuffle text which sets shuffle text to be in a different order. So, I, so the I is still linked with our original characters. So, this would be 0, this would be 1, whatever, I don't know how to use a mouse. One of these would be 2, one of these would be 3, I don't know which way around. 4, 5. And that's how view can tell that we've reordered it, instead of just replacing them with new letters in a different order.
The final kind of animation that we are going to look at is state transitions. So, here, this isn't really specific to V, but it works well with V. So, here we've got some state. I'll just show you this here.
12. Animating Numbers and SVGs
It's a number. We're using gsap again to animate the state to the new value. This demo showcases the use of SVGs in animations. The boat swims offscreen when the button is pressed and comes back into shot when pressed again. The transition component and the G element in SVG are used to achieve this animation.
It's a number. And then we want to change it to a new number. So, if I click the button, the state is automatically animated to the new value. And the way this is working, we're using gsap again. So, gsap, in addition to being able to animate CSS values and also animate properties on any object.
So, here we've got our number ref and it's animating number.value to the new value and taking one second to do it. So, that comes in really handy sometimes. And I will show you on the next demo.
So, that was kind of all the different kinds of animations you can do with GGS. And now I figured as I'm a massive fan of SVGs, and I haven't shown any SVGs yet in this talk, I would show this demo which brings them all together. So, here we've got this boat. If I press this button, it swims offscreen and then if I press the button again, it comes back into shot.
So, this is using the transition component again. I'll just show you the code for that. So, here you can see this block here. This is our So, this here is our block and we use the G, so the G element is kind of like the div element in HTML because now we're in an SVG component. I'll just show you that. Here we go. Here it is. So, everything in here is inside an SVG component. So, it looks like HTML, but it's not. It's still XML, so it's pretty readable. But it's slightly different. So, here we've got our G element, which it stands for group and inside we have our boat. And when the G class becomes visible, so we've got our boat visible variable, which is set to true or false by the button. And here we've got...it's wrapped in our transition component, which you'll recognize these by now. And it adds and removes the transform. So, when you click it, it goes out using a transform, and then it comes back in again using a different transform. Here for these clouds, we're using transition group. So, I'll just span that a bit.
13. Animating Elements and State Transitions
We explore the animation of elements being added and removed from an array using Vue's transition group. We also discuss state transitions using a time value that affects multiple components. GSAP is used to smoothly animate the number when a button is clicked. This part summarizes the different animation types in one SVG.
It's adding more to an array, and then if I span remove, it's removing them from the array, and it's animating them in and out. So, let's have a look at that. So, on the left, you can see right at the top, we've got our clouds array. It's our array of clouds, their positions and sizes, and then we've got two functions, addCloud and removeCloud, which is pushing new, it generates a new cloud, or removes a cloud. And then here on the right, we've got our transition group, which contains our clouds, again, using a v4, and then in our style at the bottom, we've got our CSS, which handles entering and removing. So, it comes in from the left with opacity zero, and it leaves to the right again with opacity zero. So, our clouds aren't changing direction or anything, it's using different from and to positions.
And finally, we've got our state transitions. So, here, everything I'll show you in the code. So, we've got a time value, which it's a ref, which defaults to 18, so 6pm. And then this is being passed into a bunch of different components. So, for example, this is the moon component. Our moon component on the right here, it's being given a time prop and then we're changing the moon opacity depending on what time it is. So, for example, there is no moon now because it's during the day. So, we've got this number and when we change it, lots of different elements will change states. So, for example, some of them are changing color, some of them are changing opacity, some of them are changing position, such as the sun and opacity like the moon. So, that isn't an animation. That is an animation because I just dragged the handle slowly, but that isn't actually an animation. So, the animation here is we're using GSAP again so that when we click a button, it smoothly animates that number. So, right now, the number is 18. I click this button, it's going to animate it to 12 and we can see the effect of that on our animation. Cool. So, that's the summary of all the animation types in one SVG. So, we've looked at transitions without a group, so the boat going in and out and we've looked at transition groups, the clouds and then we've looked at state transitions. And that's it for my talk.