Animation can explain whatever the mind can conceive. When animation is functionally applied to a website or app, the event flow can easily map with the user's ability to navigate through the app.
In the post Animating React Applications, we covered multiple ways to animate in React, including mounting and unmounting animations without explicitly using the lifecycle hooks. We were able to do this simply with ReactCSSTransitionGroup and better with other tools like ReactMotion and ReactMove. Vue ships with transition components that operate in a similar way. They are <transition>
and <transitionGroup>
.
Let us back up a bit and answer the question: Why use Vue? Like React, Vue is an interesting view rendering tool that helps build applications with separation of concerns. It has a good diffing algorithm for optimal DOM operations, and it follows the web components spec which apparently seem like the direction the web is headed for. If JavaScript has stopped being fun for you, you could find the again with Vue.
The Vue transition components help with simple interpolated animations between states rather than fully declared animation. For the difference between both, look at the handbook.
With the syntax simplicity in Vue, we could achieve a content visibility toggle with v-if
while toggling the state with a button trigger as shown below:
The sudden visual state change makes the experience unsavory. This is where transitions come in. By wrapping that changing visual element in a transition, we could achieve a more pleasant UX.
The demo above has the following
<ul class="list" v-if="isDropped">
<li>Dog</li>
<li>Cat</li>
<li>Bunny</li>
<li>Parrot</li>
<li>Fish</li>
</ul>
and it would take the new form:
<transition>
<ul class="list" v-if="isDropped">
<li>Dog</li>
<li>Cat</li>
<li>Bunny</li>
<li>Parrot</li>
<li>Fish</li>
</ul>
</transition>
but simply adding a transition wrapper does not smoothen the experience as there are no built-in transition effects.
Creating a transition tag exposes some CSS classes to be applied to the child element when mounted to the DOM. Classes like .v-enter
, .v-leave-to
, which are descriptive enough in what they do by their names. The animation can be interpolated with a transition or more animation using .v-enter-active
or .v-leave-active
. The .v
class namespace can be changed by adding a name attribute to the transition like:
<transition name="slide">
</transition>
Then we can write our animations in the CSS
.slide-enter, .slide-leave-to{
transform: scaleY(0)
}
.slide-enter-active, .slide-leave-active{
transition: transform 0.5s ease-in-out;
}
The active transition classes can be skipped if already applied to the main class like in the example here:
To understand how transitions are being applied to lifecycle mount and unmount states, see this section from the react animation post.
The illustration below also clearly explains how the classes get added with the use of transition component.
If you would rather have predefined transitions without having to declare them explicitly in the CSS, the transition component can also be used with animate.css without introducing any third party app:
<transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight" >
<p v-if="show">hello</p>
</transition>
The name attribute needs merely to have an animate.css class name as value.
The <transitionGroup>
component works similarly enough to the transition component, but as the name implies, it works better when animating a group of things. A typical example is animation of items on a list.
In the example above, where I needed to use a key handler (enter) to enter the input, I could have had the method in the JS this way:
updateList(e){
if(e.keyCode === 13){
const petname = e.target.value
this.pets.unshift(petname)
e.target.value = ''
}
}
however, with Vue event handling, reactive/interactive animations can be made easier with common key modifiers
<input @keypress.enter="updateList">
updateList(e){
const petname = e.target.value
this.pets.unshift(petname)
e.target.value = ''
}
Here is a more interesting example of <transition-group>
with a FLIP animation.
We can eliminate third-party libraries by leveraging the built-in features of Vue.
To learn more about Vue transitions, you should look in the docs which covers directives like mode
, appearance
, and so much more.
Previous transition component examples base on interpolating animations between the mount and unmount states or vice-versa, and with transition-group, we could animate the position update of items in a list. That leaves the question, how can a mounted state be transitioned to another mounted state? Vue provides a watchers method for that. It monitors the state changes of a section of the DOM and provides access to create tweens between them.
By adding a watcher here, the new state of the checkbox can be derived in its callback as well as the old state. So a tween can be created from oldState to newState. This example uses GSAP TextPlugin to toggle Activate and Deactivate as the toggler state changes.
The documentation covers more state transition examples with dynamic state transitions.
We can achieve many more interesting animations in our applications by introducing these tweening libraries.
Velocity.js and GSAP especially have pushed the capabilities of web animations since the era of flash. There are other great tweeting libraries like Popmotion, JustAnimate, and more but I will simply demonstrate how GSAP can be used with Vue.
In this example, the emoji expression is being morphed with the GSAP morphSVG plugin as the range input changes. More interestingly, the submission uses TimelineMax to go through various stages till a finished checkbox.
Applying the things learned so far we can begin to apply some animation techniques for dataviz.
The demo above by Shaw combines Greensock's morphSVG, GSAP, and D3 in a Vue environment.
Sarah Drasner who happens to be a Vue, SVG, and animation expert has also created the following data visualization demo using Vue.
This example takes advantage of the built-in math ability of svg and adds Vue's logic making it not to require any external chart library.
Sections of the svg can be separated as their own components and Vue directives can be used on the SVG.
Sarah also gave an interesting talk where she explains things like hooking animations to custom directives, that can be found here.
If you would rather use a library like chart.js, this linked pen shows examples of representing datasets in donuts and line graphs. There is also a vue wrapper for chart.js.
Vue is a flexible view library, and its ease of use makes it delightful to build complex animations with little or no complications at all. It works great with popular animation libraries and more tools keep getting made to make working with Vue as a frontend developer astonishing. There is a Vue extension for Lottie and for Three.js which have proven to be invaluable tools in interactive front end development. It can only get better.