8 Animating Your Application with Transitions and CSS

To have a more dynamic application and have the full attention of the user, using animation is crucial. Today, CSS animations are present in toasts, banners, notifications, and even input fields.

There are some cases where you need to create special animations, known as transitions, and have full control of what is happening on your page. To do this, you must use custom components and have the framework to help you with rendering your application.

With Vue, we can use two custom components that can help us create animations and transitions in our application with the help of CSS classes. Those components are Transition and TransitionGroup.

In this chapter, we will learn how to create a CSS animation, use the Animate.css framework to create a custom transition, use the Transition component hook to execute custom functions, create animations that execute on the render of the component, create animations and transitions for groups and lists, create reusable custom transition components, and create seamless transitions between components.

In this chapter, we'll cover the following recipes:

  • Creating your first CSS animation

  • Creating a custom transition class with Animate.css

  • Creating transactions with custom hooks

  • Creating animations on page render

  • Creating animations for lists and groups

  • Creating a custom transition component

  • Creating a seamless transition between elements

Technical requirements

In this chapter, we will be using Node.js and Vue-CLI.

Attention Windows users! You need to install an NPM package called windows-build-tools to be able to install the following required packages. To do so, open PowerShell as an Administrator and execute the
> npm install -g windows-build-tools command.

To install Vue-CLI, you need to open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command:

> npm install -g @vue/cli @vue/cli-service-global

Creating the base project

In this chapter, we will use this project as the base for each recipe. Here, I will guide you through how to create the base project:

  1. Open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command:

> vue create {replace-with-recipe-name}

  1. Vue-CLI will ask for you to choose a preset; select Manually select features using the spacebar:

? Please pick a preset: (Use arrow keys)
default (babel, eslint)
Manually select features

  1. Now, Vue-CLI will ask for what features you wish to install. You will need to select CSS Pre-processors as an additional feature on top of the default ones:

? Check the features needed for your project: (Use arrow keys)
Babel
TypeScript
Progressive Web App (PWA) Support
Router
Vuex
CSS Pre-processors
Linter / Formatter
Unit Testing
E2E Testing

  1. Continue this process by selecting a linter and formatter. In our case, we will select ESLint + Airbnb config:

? Pick a linter / formatter config: (Use arrow keys)
ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
ESLint + Prettier

  1. Choose the additional features of the linter. In our case, select the Lint on save and Lint and fix on commit:

? Pick additional lint features: (Use arrow keys)
Lint on save
Lint and fix on commit

  1. Select where you want to place the linter and formatter configuration files. In our case, we will select In dedicated config files:

? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
In dedicated config files
In package.json

  1. Finally, the CLI will ask you whether you want to save the settings for future projects; select N. After that, Vue-CLI will create the folder and install the dependencies for you:

? Save this as a preset for future projects? (y/N) n

  1. From the created project, open the App.vue file, which is located in the src folder. In the <script> section of the single file component, remove the HelloWorld component. Add a data property and define it as a singleton function that's returning a JavaScript object with a property named display, and with a default value of true:

<script>
export default {
name: 'App',
data: () => ({
display: true,
}),
};
</script>

  1. In the <template> section of the single file component, remove the HelloWorld component and add a button HTML element with the text Toggle. In the img HTML element, add a v-if directive bounded to the display variable. Finally, in the button HTML element, add a click event. In the event listener, define the value as an anonymous function that sets the display variable as the negation of the display variable:

<template>
<div id="app">
<button @click="display = !display">
Toggle
</button>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png">
</div>
</template>

With these instructions, we can create a base project for each recipe in this chapter. 

Creating your first CSS animation

With the help of CSS, we can animate our application without the need to manually program the changes of DOM elements through JavaScript. Using special CSS properties dedicated exclusively to controlling animations, we can achieve beautiful animations and transitions.

To use the animations that are available in Vue, we need to use a component called Transition when an animation is being applied to a single element or a component called TransitionGroup when dealing with a list of components.

In this recipe, we will learn how to create a CSS animation and apply this animation to a single element on the Vue application.

Getting ready

The following are the prerequisites for this recipe:

  • Node.js 12+

  • A Vue-CLI base project called cssanimation

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called cssanimation and open the project folder. Now, follow these steps:

  1. Open the App.vue file. In the <template> section of the single file component, wrap the img HTML element with a Transaction component. In the Transaction component, add a name attribute with a value of "image":

<transition name="image">
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png">
</transition>

  1. In the <style> section of the single file component, create an .image-enter-active class with an animation property that has a value of bounce-in .5s. Then, create an .image-leave-active class with an animation property that has a value of bounce-in .5s reverse:

.image-enter-active {
animation: bounce-in .5s;
}
.image-leave-active {
animation: bounce-in .5s reverse;
}

  1. Finally, create a @keyframes bounce-in CSS rule. Inside it, do the following:

    • Create a 0% rule with a property transform and a value of scale(0).

    • Create a 50% rule with a property transform and a value of scale(1.5).

    • Create a 100% rule with a property transform and a value of scale(1):

@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}

After doing this, your image will scale up and disappear when the toggle button is pressed for the first time. When pressed again, it will scale up and stay in the correct scale after the animation has finished:

How it works...

First, we added the Vue animation wrapper to the element we wanted to add the transition to, and then added the name of the CSS class that will be used on the transition. 

The Transition component uses pre-made namespaces for the CSS class that are required to be present. These are -enter-active, for when the component enters the screen, and -leave-active, for when the component leaves the screen.

Then, we create the CSS classes in <style> for the transition of the element to leave and enter the screen, and the keyframe ruleset for the bounce-in animation in order to define how it will behave.

See also

You can find more information about class-based animation and transitions with Vue classes at https://v3.vuejs.org/guide/transitions-overview.html#class-based-animations-transitions.

You can find more information about CSS keyframes at https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes.

Creating a custom transition class with Animate.css

In the Transition component, it is possible to define the CSS classes that will be used in each transition step. By using this property, we can make the Transition component use Animate.css in the transition animations.

In this recipe, we will learn how to use the Animate.css classes with the Transition component in order to create custom transitions in our components.

Getting ready

The following are the prerequisites for this recipe:

  • Node.js 12+

  • A Vue-CLI base project called animatecss

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called animatecss and open the project folder. Now, follow these steps:

  1. Inside the project folder, open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command to install the Animate.css framework:

> npm install [email protected]

  1. Open the main.js file in the src folder and import the Animate.css framework:

import Vue from 'vue';
import App from './App.vue';
import 'animate.css';

  1. Open the App.vue file in the src folder and add a Transition component as a wrapper for the img HTML element. In the Transition component, add an attribute called enter-active-class and define it as "animated bounceInLeft". Then, add another attribute called leave-active-class and define it as "animated bounceOutLeft":

<transition
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutLeft"
>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png">
</transition>

After doing this, your image will slide out to the left and disappear when the toggle button is pressed for the first time. When pressed again, it will slide in from the left:

How it works...

The Transition component can receive up to six props that can set up custom classes for each step of the transaction. Those props are enter-class, enter-active-class, enter-to-class, leave-class, leave-active-class, and leave-to-class. In this recipe, we used enter-active-class and leave-active-class; these props defined the custom classes for when the element is visible on the screen or leaves the screen.

To use custom animations, we used the Animate.css framework, which provides custom CSS animations that have been pre-made and ready for use. We used bounceInLeft and bounceOutLeft in order to make the element slide in and out from the screen.

There's more...

You can try to change the classes of the enter-active-class and leave-active-class props for any of the props available on Animate.css and see how the CSS animation behaves on the browser.

You can find the full list of available classes in the Animate.css documentation at https://animate.style/.

See also

You can find more information about class-based animation and transitions with Vue classes at https://v3.vuejs.org/guide/transitions-overview.html#class-based-animations-transitions.

You can find more information about Animate.css at https://animate.style/.

Creating transactions with custom hooks

The Transaction component has custom event emitters for each animation life cycle. These can be used to attach custom functions and methods to be executed when the animations cycle is completed.

We can use these methods to execute data fetches after the page transaction completes or a button animation ends, thus chaining animations in a specific order that need to be executed one after another based on dynamic data.

In this recipe, we will learn how to use the custom event emitters of the Transaction component to execute custom methods.

Getting ready

The following are the prerequisites for this recipe:

  • Node.js 12+

  • A Vue-CLI base project called transactionhooks

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called transactionhooks and open the project folder. Now, follow these steps:

  1. Inside the project folder, open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command to install the Animate.css framework:

> npm install [email protected]

  1. Open the main.js file in the src folder and import the Animate.css framework:

import Vue from 'vue';
import App from './App.vue';
import 'animate.css';

  1. Open the App.vue file in the src folder. In the <script> section of the single file component, in the data property, in the singleton function, add a new property called status with the value defined as "appeared":

data: () => ({
display: true,
status: 'appeared',
}),

  1. Create a methods property and define it as a JavaScript object. Inside the object, add two properties called onEnter and onLeave. In the onEnter property, define it as a function, and inside of it, set the data status variable to"appeared". In the onLeave property, define it as a function, and inside of it set the data status variable to "disappeared":

methods: {
onEnter() {
this.status = 'appeared';
},
onLeave() {
this.status = 'disappeared';
},
},

  1. In the <template> section of the single file component, add a Transition component as a wrapper for the img HTML element. In the Transition component, do the following:

    • Add an attribute called enter-active-class and define it as "animated rotateIn".

    • Add another attribute called leave-active-class and define it as "animated rotateOut".

    • Add an event listener after-enter bind and attach it to the onEnter method.

    • Add an event listener after-leave bind and attach it to the onLeave method:

<transition
enter-active-class="animated rotateIn"
leave-active-class="animated rotateOut"
@after-enter="onEnter"
@after-leave="onLeave"
>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png">
</transition>

  1. Create an h1 HTML element as a sibling of the Transition component and add the text The image {{ status }}:

<h1>The image {{ status }}</h1>

Now, when the button is clicked, the text will change when the animation finishes. It will show The image appeared when the animation finishes entering and The image disappeared when the animation has finished leaving:

How it works...

The Transition component has eight custom hooks. These hooks are triggered by the CSS animations and when they are triggered, they emit custom events, which can be used by the parent component. These custom events are before-enterenter, after-enter, enter-cancelled, before-leave, leave, after-leave, and leave-cancelled

When using the after-enter and after-leave hooks, when the CSS animations have finished, the text on the screen changes accordingly to the functions that have been defined on the event listeners for each hook.

See also

You can find more information about transition hooks at https://v3.vuejs.org/guide/transitions-enterleave.html#javascript-hooks.

You can find more information about Animate.css at https://animate.style/.

Creating animations on page render

Using page transition animations or custom animations that are displayed on the render of a page is common and sometimes needed to catch the attention of the user of an application. 

It's possible to create this effect in a Vue application without the need to refresh the page or re-render all the elements on the screen. You can do this using the Transition component or the TransitionGroup component.

In this recipe, we will learn how to use the Transition component so that the animation is triggered when the page is being rendered.

Getting ready

The following are the prerequisites for this recipe:

  • Node.js 12+

  • A Vue-CLI base project called transactionappear

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called transactionappear and open the project folder. Now, follow these steps:

  1. Inside the project folder, open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command to install the Animate.css framework:

> npm install [email protected]

  1. Open the main.js file in the src folder and import the Animate.css framework:

import Vue from 'vue';
import App from './App.vue';
import 'animate.css';

  1. Open the App.vue file in the src folder and add a Transition component as a wrapper for the img HTML element. In the Transition component, do the following:

    • Add an attribute called appear-active-class and define it as "animated jackInTheBox".

    • Add an attribute called enter-active-class and define it as "animated jackInTheBox".

    • Add another attribute called leave-active-class and define it as "animated rollOut".

    • Add the appear attribute and define it as true:

<transition
appear
appear-active-class="animated jackInTheBox"
enter-active-class="animated jackInTheBox"
leave-active-class="animated rollOut"
>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png">
</transition>

When the page opens, the Vue logo will shake like a jack-in-the-box and will be static after the animation has finished running: 

How it works...

The Transition component has a special property called appear that, when enabled, makes the element trigger an animation when it is rendered on the screen. This property comes with three properties for controlling the animation CSS classes, which are called appear-class, appear-to-class, and appear-active-class.

There are four custom hooks that are executed with this property as well, which are called before-appear, appear, after-appear, and appear-cancelled.

In our case, we made the component execute the jackInTheBox animation from the Animate.css framework when the component gets rendered on-screen.

See also

You can find more information about transitions on initial render at https://v3.vuejs.org/guide/transitions-enterleave.html#transitions-on-initial-render.

You can find more information about Animate.css at https://animate.style/.

Creating animations for lists and groups

There are some animations that need to be executed within a group of elements or a list. These animations need to be wrapped in a TransitionGroup element in order to work. 

This component has some properties that are the same as the ones in the Transition component, but to get it working, you have to define a set of special instructions for the child elements and the components that are specific to this component.

In this recipe, we will create a dynamic list of images that will be added when the user clicks on the respective button. This will execute the animation when the image appears on the screen.

Getting ready

The following are the prerequisites for this recipe:

  • Node.js 12+

  • A Vue-CLI base project called transactiongroup

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called transactiongroup and open the project folder. Now, follow these steps:

  1. Inside the project folder, open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command to install the Animate.css framework:

> npm install [email protected]

  1. Open the main.js file in the src folder and import the Animate.css framework:

import Vue from 'vue';
import App from './App.vue';
import 'animate.css';

  1. Open the App.vue file in the src folder. In the <script> section of the single file component, on the data singleton, return a property called count with a value of 0:

data: () => ({
count: 0,
}),

  1. In the <template> section of the single file component, remove everything inside the div#app HTML element. Then, as a child of the div#app HTML element, create a TransitionGroup component with an attribute called tag defined as "ul" and an attribute called enter-active-class defined as "animated zoomIn":

<div id="app">
<transition-group
tag="ul"
enter-active-class="animated zoomIn"
></transition-group>
</div>

  1. As a child of the TransitionGroup component, create a li HTML element with the v-for directive, iterating over the count variable as i in count. Add a variable attribute called key defined as i and a style attribute defined as "float: left". As a child of the li HTML component, create an img HTML component with the src attribute defined as "https://picsum.photos/100":

<li
v-for="i in count"
:key="i"
style="float: left"
>
<img src="https://picsum.photos/100"/>
</li>

  1. Then, as a sibling element of the TransitionGroup component, create a hr HTML element with the style attribute defined as "clear: both":

<hr style="clear: both"/>

  1. Finally, as a sibling of the hr HTML element, create a button HTML element with the click event, adding 1 to the current count variable and setting the text to Increase:

<button
@click="count = count + 1"
>
Increase
</button>

Now, when the user clicks the respective button to increase the list, it will add a new item to the list and the zooming in animation will trigger:

How it works...

The TransitionGroup element creates a wrapper element with the tag you declared in the tag property. This will manage the custom elements that will trigger the animation by checking the unique identity of the child elements by their unique keys. Because of this, all the child elements inside the TransitionGroup component need to have a key declared and have to be unique.

In our case, we created an HTML list using a combination of ul and li HTML elements, where TransitionGroup was defined with the ul tag and the child elements were defined with the li HTML elements. Then, we created a virtual iteration over a number. This means there will be a list of items and display images on-screen according to the number of items on that list.

To increase our list, we created a button HTML element that increased the count of the count variable by one each time it was pressed.

See also

You can find more information about transition groups at https://v3.vuejs.org/guide/transitions-list.html#reusable-transitions.

You can find more information about Animate.css at https://animate.style/.

Creating a custom transition component

Using a framework to create an application is good because you can make reusable components and shareable code. Using this pattern is great for simplifying the development of the application. 

Creating a reusable transition component is the same as creating a reusable component and can have a simpler approach as it can be used with functional rendering instead of the normal rendering method.

In this recipe, we will learn how to create a reusable functional component that can be used in our application.

Getting ready

The following are the prerequisites for this chapter:

  • Node.js 12+

  • A Vue-CLI base project called customtransition

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called customtransition and open the project folder. Now, follow these steps:

  1. Inside the project folder, open Terminal (macOS or Linux) or a Command Prompt/PowerShell (Windows) and execute the following command to install the Animate.css framework:

> npm install [email protected]

  1. Open the main.js file in the src folder and import the Animate.css framework:

import Vue from 'vue';
import App from './App.vue';
import 'animate.css';

  1. Create a new file named CustomTransition.vue in the src/components folder and open it. In the <template> section of the single file component, add the functional attribute to enable the functional rendering of the component. Then, create a Transition component, with the appear variable attribute defined as props.appear. Define the enter-active-class attribute as "animated slideInLeft" and the leave-active-class attribute as "animated slideOutRight". Finally, inside the Transition component, add a <slot> placeholder:

<template functional>
<transition
:appear="props.appear"
enter-active-class="animated slideInLeft"
leave-active-class="animated slideOutRight"
>
<slot />
</transition>
</template>

  1. Open the App.vue file in the src folder. In the <script> section of the single file component, import the newly created CustomTransition component. On the Vue object, add a new property called components, define it as a JavaScript object, and add the imported CustomTransition component:

<script>
import CustomTransition from './components/CustomTransition.vue';

export default {
name: 'App',
components: {
CustomTransition,
},
data: () => ({
display: true,
}),
};
</script>

  1. Finally, in the <template> section of the single file component, wrap the img HTML element with the CustomTransition component:

<custom-transition>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png">
</custom-transition>

With this custom component, it's possible to reuse the transition without the need to redeclare the Transition component and the transition CSS classes on the component:

How it works...

First, we created a custom component using the functional component method, where there is no need to declare the <script> section of the single file component.

In this custom component, we used the Transaction component as the base component. Then, we defined the appear attribute with the injected functional context, prop.appear, and added the animations classes for the transition to slide in from the left when the component is rendered and slide out from the right when it's destroyed.

Then, in the main application, we used this custom component to wrap the img HTML element and make it work as the Transition component.

See also

You can find more information about reusable transition components at https://v3.vuejs.org/guide/transitions-list.html#reusable-transitions.

You can find more information about Animate.css at https://animate.style/.

Creating a seamless transition between elements

When there are animations and transitions between two components, they need to be seamless so that the user won't see the DOM shaking and redrawing itself when the components are being placed on the screen. To achieve this, we can use the Transition component and the transition mode property to define how the transition will occur.

In this recipe, we will create a transition between images using the Transition component and the transition mode attribute to create a seamless animation.

Getting ready

The following are the prerequisites for this chapter:

  • Node.js 12+

  • A Vue-CLI base project called seamlesstransition

The Node.js global objects that are required are as follows:

  • @vue/cli

  • @vue/cli-service-global

How to do it...

Using the base project, create a new project for this recipe called seamlesstransition and open the project folder. Now, follow these steps:

  1. Open the App.vue file in the src folder. In the <style> section of the single file component, create a property called .rotate-enter-active,.rotate-leave-active and define the transition CSS style property as transform .8s ease-in-out;. Then, create a property called .rotate-enter,.rotate-leave-active and define the transform CSS style property as rotate( -180deg ); and transition as .8s ease-in-out;:

.rotate-enter-active,
.rotate-leave-active {
transition: transform .8s ease-in-out;
}

.rotate-enter,
.rotate-leave-active {
transform: rotate( -180deg );
transition: transform .8s ease-in-out;
}

  1. In the <template> section of the single file component, wrap the img HTML element with a Transition component. Then, define the name attribute as rotate and the mode attribute as out-in:

<transition
name="rotate"
mode="out-in"
></transition>

  1. Inside the Transition component, in the img HTML element, add a key attribute and define it as up. Then, add another img HTML element and add a v-else directive. Add a key attribute and define it as down, add an src attribute and define it as "./assets/logo.png", and finally add a style attribute and define it as "transform: rotate(180deg)":

<img
v-if="display"
key="up"
src="./assets/logo.png">
<img
v-else
key="down"
src="./assets/logo.png"
style="transform: rotate(180deg)"
>

When the user toggles the element, the leaving animation will be executed, and then after it has finished, the entering animation will start with no delay. This makes for a seamless transition between the old element and the new one:

How it works...

The Transition component has a special attribute called mode, where it is possible to define the behavior of the element's transition animation. This behavior will create a set of rules that controls how the animation steps will occur inside the Transition component. It's possible to use "in-out" or "out-in" mode in the component:

  • In the "in-out" behavior, the new element transition will occur first, and when it's finished, the old element transition will start.

  • In the "out-in" behavior, the old element transition will occur first, and then the new element transition will start.

In our case, we created an animation that rotates the Vue logo upside down. Then, to handle this seamless change, we used "out-in" mode so that the new element will only show up after the old one has finished the transition.

See also

You can find more information about transition modes at https://v3.vuejs.org/guide/transitions-enterleave.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.85.183