DEV Community

Matthew Piercey
Matthew Piercey

Posted on • Updated on

Nuxt, Meet Anime

This article is part of a series on my experiences with Nuxt.js that I built into the nuxt-toolkit by OverScore Media

GitHub logo overscore-media / nuxt-toolkit

A bunch of useful example code snippets for use with Nuxt.js

See a live example at https://nuxt-toolkit.overscore.media! :]


You Thought This was a Meme Alt Text, but it was Me, DIO!

Aight, Elephant in the room, the only Anime series I've actually watched start-to-end is Rockman EXE (Plus Axess, Stream, Beast, and Beast +. And both seasons of Ryuusei no Rockman).

Rockman EXE anime GIF

For those of you who haven't been enlightened, Rockman EXE and its suprisingly-large list of successors is a series set in a universe based on a bunch of GBA games where MegaMan is a tamagotchi. It's my guilty pleasure show (outside of the first three seasons of Arrested Development). For those of you who have, "Plug In - Rockman EXE - POWER UP!"

That Aside Aside...

So, Anime.js by Julian Garnier and co.. The incredible JavaScript animations library. I personally love it, since I think it's so declarative and extensible. And, hey, it may not be the smallest out there, but it packs a lot of punch for its 17KB size.

But how, pray tell, would one go about integrating Anime.js in one's Nuxt app?

It's really not all that difficult.

The way I see it, you have two main options here. You can either load in animejs itself, or you can use the vue-anime directive.

Honestly, it's your call. The former means a (slightly) lower bundle size (Maybe? I actually don't know) and makes it a bit easier to write the animation code, but the latter lets you plug in animations directly in the template of your Vue components (and by extension, Nuxt pages and layouts). If you're used to Vue, I'd recommend the directive, but I'll show both ways and let you make up your own mind. Besides, you can experiment once you know the options available to you.

Either way you decide to import/use it, Anime.js's documentation is invaluable. If in doubt, check the docs! :) One thing you do need to know, though, is that Anime works well with CSS transforms/translates. That being said, you might think that a translateX: 100 will move your object 100 pixels. Technically, you'd be right, but more specifically it adds the translation directly to the object. So it's relative to the object's initial position, I think. If that makes sense. If it doesn't, you'll figure it out soon enough. Trust me; if I did, you can too. I wish I could teach you how to learn everything you wanted to learn, but believe it or not, you're your best teacher. You know how you learn. Don't sell yourself short, but don't worry about meeting your own expectations... Well, OK then. Let's continue!

Way 1: Direct Usage

First, install Anime.js with yarn add animejs or your NPM equivalent (npm install --save animejs I think).

Then you can use it. Here's a bare-bones example. Note the import of animejs/lib/anime.es.js and the use of the Vue mounted hook, and the process.browser to check if the code is running on a browser (and not a server... it's a Nuxt thing).

<template>
  <!-- -->
  <div class="target-class"></div>
  <!-- -->
</template>

<script>
import anime from 'animejs/lib/anime.es.js'

export default {
// ...
  mounted: {
    if (process.browser) {
      anime({
        targets: '.target-class',
        translateX: 100,
        duration: 2000
      })
    }
  }
// ...
</script>
Enter fullscreen mode Exit fullscreen mode

Way 2: Directive Usage

First off, thank you @BenAHammond on GitHub for coming up with the idea for the vue-anime directive.

GitHub logo BenAHammond / vue-anime

A Vue plugin for adding Anime bindings to Vue components

Next, install it with yarn add vue-animejs or npm install --save vue-animejs

Wait, I figured out the difference between NPM and Yarn. NPM is Node's oh-my-zsh, and Yarn is Node's antigen. If you don't use zsh, you probably have no idea what I'm talking about. Regardless, they're two tools (the latter of which depends on the former sorta to be fully functional) that basically do the same thing, but some people like one more than the other. Isn't the development world exciting? Yes, it is; whether or not you like excitement, you can't deny that. Oh, I went and wrote a whole paragraph about basically nothing. You still there, by chance? Hi!

To regain my bearings, I'll tell you that you next need to make a Nuxt plugin in the ~/plugins directory of your Nuxt app. I named mine anime.js and it has this content:

import Vue from 'vue'
import VueAnime from 'vue-animejs'

Vue.use(VueAnime)

Enter fullscreen mode Exit fullscreen mode

I then imported said plugin in my nuxt.config.js in the plugins section like this:

// ...
plugins: [
  '~/plugins/anime.js'
],
// ...
Enter fullscreen mode Exit fullscreen mode

Finally, use the directive. Either use it directly (as in this example from the directive's GitHub repo):

<div v-anime="{ rotate: '1turn', backgroundColor: '#FFF', duration: 2000, loop: true }"></div>
Enter fullscreen mode Exit fullscreen mode

Or put something like this in the <script> tag of your Vue component/page/layout:

// ...
const animeDiv = this.$el.getElementsByClassName('target-class')
// ...
this.$anime({
   targets: animeDiv,
   background: ['#fff', '#000'],
   duration: 3000,
   loop: true,
   direction: 'alternate'
})
// ...
Enter fullscreen mode Exit fullscreen mode

Either way, pretty cool! Pretty Cool Bananas

Have fun, everybody, and keep on coding! Hope this was helpful.

Latest comments (2)

Collapse
 
dreaminder profile image
DreaMinder • Edited

"...and the process.browser to check if the code is running on a browser (and not a server... it's a Nuxt thing)."

This check doesn't make sense inside of mounted hook, it's triggered on client-side only.

Collapse
 
mtpiercey profile image
Matthew Piercey

AFAIK, not with Nuxt. I may be wrong (I'll have to test that out) but I'm pretty sure I remember it not working when I tried to do something requiring window/document. I'll have to look into that, though - because I think you're probably right.