Manage Image Animations in NuxtJS

Idris Olubisi

Animations are a powerful way to add motion to the user interface. The moving of elements is possible with animations, as well as their appearance and disappearance.

This post will teach us how to manage image animations using the Nuxt.js inbuilt animations element.

Sandbox

We completed this project in a CodeSandbox. Fork and run it to quickly get started.

GitHub repository

https://github.com/Olanetsoft/Manage-image-animations-in-Nuxt.js

Getting Started with Nuxt.js

Nuxtjs is the bedrock of our Vue.js project, providing structure and flexibility while allowing us to scale confidently.

It is extensible, offering a robust module ecosystem and hooks engine that makes it simple to integrate our REST or GraphQL endpoints, favorite CMS, CSS frameworks, and many other third-party applications.

Project Setup and Installation

To create a new project, we will use the command below to scaffold a new project:

1npx create-nuxt-app <project-name>

A series of prompts will appear as a result of the command. Here are the defaults we recommend:

The command creates a Nuxt.js project with TailwindCSS called video-ad-nuxtjs.

TailwindCSS is a CSS framework containing a lot of classes to help us customize our website's style.

Next, we navigate to the project directory and start the development server using the command below.

1cd <project name> && yarn dev

Nuxt.js will start a hot-reloading development environment accessible by default at http://localhost:3000

We proceed to install the @nuxtjs/cloudinary dependency with:

1npm install @nuxtjs/cloudinary

Configuring Cloudinary in Nuxt.js

First, we need to modify the nuxt.config.js file by adding @nuxtjs/cloudinary as a module in the modules section:

1modules: [
2 '@nuxtjs/cloudinary', //add this
3 ],

Next, we need to configure Cloudinary by adding a cloudinary section below the modules section as shown below:

1modules: [
2 '@nuxtjs/cloudinary',
3 ],
4
5 // add this
6 cloudinary: {
7 cloudName: '<your-cloud-name>',
8 useComponent: true,
9 },

The useComponent flag set to true lets us use the built-in Cloudinary components. Our cloud name is obtained from our Cloudinary dashboard.

Building the Image Animations

We can start building the image animations with our project fully set up and configured.

Inside the index.vue file let’s update it with the following code snippet to set up our layout for the project.

https://gist.github.com/Olanetsoft/dc0639196babd4eb602b35e87d7a3c63

https://gist.github.com/Olanetsoft/dc0639196babd4eb602b35e87d7a3c63

Let's open our browser, we should see something similar to the image below.

In the following section, we will implement how to manage image animations in Nuxt.js using the Class-based Animations, Built-in Transition (Toggle & Fade), CSS Transitions (Slide & Fade), CSS Animations (Bounce), and Custom Transition Classes.

Class-Based Animations

We can start animations for components that aren't entering or leaving the DOM by dynamically adding a CSS class with the following code snippet:

1<template>
2 <div
3 class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0">
4 <div class="max-w-4xl mx-auto sm:px-6 lg:px-8 mb-8">
5 //...
6 <div class="mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6">
7 <h2 class="text-lg leading-6 font-medium text-gray-900">
8 Class-based Animations
9 </h2>
10
11 <!-- Update the div class -->
12 <div :class="{ shake }">
13 <button
14 @click="shake = !shake" // Add this
15 //...
16 >
17 Click me (Shake)!
18 </button>
19
20 <!-- Add this -->
21 <cld-image
22 public-id="/samples/people/boy-snow-hoodie.jpg"
23 class="mt-3"
24 >
25 </cld-image>
26 </div>
27 </div>
28 //...
29 </div>
30 </div>
31 </template>
32
33 <script>
34 export default {
35 name: "IndexPage",
36 data() {
37 return {
38 shake: false,
39 };
40 },
41 };
42 </script>

In the code snippet above, we;

  • Created a shake state variable with a default set to false
  • Updated the class in the div referencing the shake state variable
  • Added the @click attribute to the button to set the value of the state variable when it’s clicked
  • Added a Cloudinary image with a public-id of our choice

Built-In Transition (Toggle & Fade)

In this section, we'll use the built-in <Transition> component to implement the built-in transition with toggle and fade capability. It doesn't need to be registered because it is accessible in any component's template. It is possible to apply enter and exit animations to elements or parts supplied to it via its default slot.

1<template>
2 <div
3 class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0
4 "
5 >
6 <div class="max-w-4xl mx-auto sm:px-6 lg:px-8 mb-8">
7 //...
8 <div class="mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6">
9 <h2 class="text-lg leading-6 font-medium text-gray-900">
10 Built-in Transition (Toggle & Fade)
11 </h2>
12 <button
13 @click="tFade = !tFade" // Add this
14 //...
15 >
16 Click me, I will toggle + Fade!
17 </button>
18
19 <!-- Add this -->
20 <Transition>
21 <cld-image
22 v-if="tFade"
23 public-id="/samples/people/group-picture.jpg"
24 class="mt-3"
25 ></cld-image>
26 </Transition>
27 </div>
28 //...
29 </div>
30 </div>
31 </template>
32
33 <script>
34 export default {
35 name: "IndexPage",
36 data() {
37 return {
38 //...
39 tFade: true,
40 };
41 },
42 };
43 </script>

In the code snippet above, we;

  • Created a tFade state variable with a default value of true
  • Added the @click attribute to the button to set the value of the state variable when it’s clicked
  • Added a Cloudinary image with a public-id of our choice wrapped with the built-in <Transition> component

CSS Transitions (Slide & Fade)

With the help of the transition CSS property, we can quickly describe various transitional elements, such as the attributes that should be animated, the length of the transition, and easing curves.

Another example of many attributes transitioning is seen here, with distinct durations and softening curves for entry and exit.

1<template>
2 <div
3 class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0">
4 <div class="max-w-4xl mx-auto sm:px-6 lg:px-8 mb-8">
5 //...
6 <div class="mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6">
7 <h2 class="text-lg leading-6 font-medium text-gray-900">
8 CSS Transitions (Slide & Fade)
9 </h2>
10 <button
11 @click="sFade = !sFade" // Add this
12 //...
13 >
14 Click me to toggle Slide + Fade!
15 </button>
16
17 <!-- Add this -->
18 <Transition name="slide-fade">
19 <cld-image
20 v-if="sFade"
21 public-id="/samples/people/group-picture-3.jpg"
22 class="mt-3"
23 ></cld-image>
24 </Transition>
25 </div>
26 </div>
27 </div>
28 </template>
29
30 <script>
31 export default {
32 name: "IndexPage",
33 data() {
34 return {
35 //...
36 sFade: true,
37 };
38 },
39 };
40 </script>

In the code snippet above, we;

  • Created sFade state variable with a default value of true
  • Added an @click attribute to the button to set the value of the state variable when it is clicked
  • Added a Cloudinary image with a public-id of our choice wrapped with the built-in <Transition> component and an attribute of name=``"``slide-fade``"

CSS Animations (Bounce)

In this section, we will experiment with the bounce functionality using the CSS animation with the following code snippet.

1<template>
2 <div
3 class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0">
4 <div class="max-w-4xl mx-auto sm:px-6 lg:px-8 mb-8">
5 //...
6 <div class="mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6">
7 <h2 class="text-lg leading-6 font-medium text-gray-900">
8 CSS Animations (Bounce)
9 </h2>
10 <button
11 @click="bounce = !bounce" // Add this
12 //...
13 >
14 Click me to toggle Bounce!
15 </button>
16
17 <!-- Add this -->
18 <Transition name="bounce">
19 <cld-image
20 v-if="bounce"
21 public-id="/samples/people/jazz.jpg"
22 class="mt-3"
23 ></cld-image>
24 </Transition>
25 </div>
26 </div>
27 </div>
28 </template>
29
30 <script>
31 export default {
32 name: "IndexPage",
33 data() {
34 return {
35 //...
36 bounce: true,
37 };
38 },
39 };
40 </script>

In the code snippet above, we;

  • Created a bounce state variable with a default value of true
  • Added an @click attribute to the button to set the value of the state variable when it is clicked
  • Added a Cloudinary image with a public-id of our choice wrapped with the built-in <Transition> component and an attribute of name="bounce"

Custom Transition Classes

The code snippet below shows how to pass the enter-from-class and enter-active-class props to the Transition component to specify custom transition classes.

1<template>
2 <div
3 class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0">
4 //...
5 <div class="mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6">
6 <h2 class="text-lg leading-6 font-medium text-gray-900">
7 Custom Transition Classes
8 </h2>
9 <button
10 @click="show = !show" // Add this
11 //...
12 >
13 Click me to toggle!
14 </button>
15
16 <!-- Add this -->
17 <Transition
18 name="custom-classes"
19 enter-active-class="animate__animated animate__tada"
20 leave-active-class="animate__animated animate__bounceOutRight"
21 >
22 <cld-image
23 v-if="show"
24 public-id="/samples/people/smiling-man.jpg"
25 class="mt-3"
26 ></cld-image>
27 </Transition>
28 </div>
29 </div>
30 </div>
31 </template>
32
33 <script>
34 export default {
35 name: "IndexPage",
36 data() {
37 return {
38 //...
39 show: true,
40 };
41 },
42 };
43 </script>

In the code snippet above, we;

  • Created a show state variable with a default value of true
  • Added an @click attribute to the button to set the value of the state variable when it is clicked
  • Added a Cloudinary image with a public-id of our choice wrapped with the built-in <Transition> component and an attribute of name="custom-classes"

Conclusion

This post demonstrated how to manage image animations in Nuxt.js.

Resources

You may also find these resources helpful.

Idris Olubisi

Software Engineer & Technical Writer

A Software Engineer & Technical Writer with immense knowledge and a passionate speaker about open source, blockchain, software products, and serverless technologies.