DEV Community

Cover image for How to make animations with Vuejs
Andrew Zachary
Andrew Zachary

Posted on • Updated on

 

How to make animations with Vuejs

If you are building user interfaces with Vuejs and suddenly animations knocked on UX doors, you don't have to worry. Vuejs offers a lot of flexibility to create any kind of animation (for elements and components) in response to changing state.

It provides two built-in components <Transition> and <TransitionGroup>, you can use <Transition> to wrap a single element/component or <TransitionGroup> to wrap a group of elements/components (a list was rendered by v-for for example), and then apply animations when:

  • Toggling the visibility through v-show.
  • Changing a rendering condition through v-if.
  • inserting or removing from a list.

You can assign animation to <Transition> or <TransitionGroup>, and it will be applied on their children, the animation can be:

  • css transition.
  • css animation.
  • a combination of css transition and css animation.
  • javascript animation.
  • a combination of javascript and css.
  • custom css classes.

let's have examples for every animation ...

CSS Transition

.fade-enter-from, .fade-leave-to {
 opacity: 0;
}
.fade-enter-active, .fade-leave-active {
 transition: opacity 0.3s ease-in-out;
}
Enter fullscreen mode Exit fullscreen mode

The animation name is fade it was used as a prefix for all four classes. The css class .fade-enter-from is used to init the opacity by 0 when the element enters (fade-in), and .fade-leave-to class is used to set the desired opacity to 0 when the element leaves (fade-out).

The other two classes .fade-enter-active, .fade-leave-active are wrapping the enter/leave animation parts by declaring the css transition style.

Now let's assign the animation to the <Transition> component through the name prop:

<transition name="fade" mode="out-in">
    <header v-if="animation1Toggle" class="font-mont border-b-2 border-black">
        <h1 class="text-6xl capitalize font-bold">first</h1>
    </header>
    <header v-else class="font-mont border-b-2 border-black">
        <h1 class="text-6xl capitalize font-bold">second</h1>
    </header>
</transition>
<div class="mt-8">
    <button class="text-4xl text-white font-ssp capitalize bg-black p-4" @click="animation1Toggle = !animation1Toggle">toggle fade</button>
</div>   
Enter fullscreen mode Exit fullscreen mode

When the animation1Toggle value changed (true/false), v-if will destroy or render the elements and as a result, the <Transition> component will load:

  • .fade-enter-from + .fade-enter-active classes when the element enters (means to be rendered) that will animate the opacity from 0 to 1.
  • .fade-leave-to + .fade-leave-active classes when the element leaves (means to be destroyed) that will animate the opacity from 1 to 0.

Also prop mode=out-in is very important because it tells <Transition> component not to start the enter-animation until leave-animation is finished.

CSS Animation

.zoom-enter-active {animation: zoom-in 1s ease-in-out;}
.zoom-leave-active {animation: zoom-out 1s ease-in-out;}
@keyframes zoom-in {
    from {transform: scale(0,0);}
    to {transform: scale(1,1);}
}
@keyframes zoom-out {
    from {transform: scale(1,1);}
    to {transform: scale(0,0);}
}
Enter fullscreen mode Exit fullscreen mode

Instead of css-transition you can use css-animation, within this example zoom-in and zoom-out animations were created by declaring .zoom-enter-active and .zoom-leave-active classes and keyframes, as a result a new animation called zoom will be available and can be applied to <Transition> component.

Combination of Transition and Animation

.zoom-fade-enter-active {
    animation: zoom-in 0.3s ease-in-out;
    transition: opacity 1s ease-in-out;
}
.zoom-fade-leave-active {
    animation: zoom-out 1s ease-in-out;
    transition: opacity 0.3s ease-in-out;
}
.zoom-fade-enter-from, .zoom-fade-leave-to {opacity: 0;}
@keyframes zoom-in {
    from {transform: scale(0,0);}
    to {transform: scale(1,1);}
}
@keyframes zoom-out {
    from {transform: scale(1,1);}
    to {transform: scale(0,0);}
}
Enter fullscreen mode Exit fullscreen mode

Both CSS transition and CSS animation can be used together but, you have to tell <Transition /> component which duration to pick through prop type within this case <transition ... type="transition">.

Javascript Animation

const beforeEnter1 = (el) => {
    console.log('before-enter');
}
const enter1 = (el, done) => {
    const animation = el.animate([{'transform': 'scale(2, 0)'}, {}], {'duration': 300});
    animation.onfinish = () => done();
}
const afterEnter1 = (el) => {
    console.log('after-enter');
}
const beforeLeave1