Create your account

Already have an account? Login here

Note: By joining, you will receive periodic emails from Coursetro. You can unsubscribe from these emails.

Create account

JavaScript Animation Tutorial - Animate your UI with Popmotion

By Gary simon - Dec 21, 2017

In this day and age, there's no reason not to integrate UI animation! Popmotion is a JavaScript Animation Library and it's very lightweight, coming in at 11kb for the total package.

I'm going to show you how to use this awesome library to animate your UI elements with ease. One thing worth mentioning is that this tutorial will not be exhaustive. Popmotion is quite feature-heavy, and would need an entire course to cover all that it offers. Instead, I will cover some of the core concepts and introduce you to their API docs, so that you can have confidence going forward.

Let's get started!

If you prefer watching a video..

Be sure to Subscribe to the Official Coursetro Youtube Channel for more videos.

Starting the Project

While you can use Popmotion with a variety of frontend JS frameworks like React, Vue and Angular, we're going to make it framework-agnostic by doing everything in plain (vanilla) JavaScript.

So, to begin, let's use the console to create a new project folder and hop into it:

$ mkdir js-animation && cd js-animation

Next, we'll use NPM (Node Package Manager) to create a new package.json file to save Popmotion as a dependency:

Note: You will need Node.js installed to access npm:

$ npm init -y

Then, we'll use npm to install popmotion and save it as a depency to our package.json file:

$ npm install popmotion --save

Great, if you're working with Visual Studio Code, just type the following command to open up VSC within the new project folder:

$ code .

Integrating Popmotion

In our new project folder, let's create an index.html file with the following code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JavaScript Animation Tutorial</title>
    <link rel="stylesheet" href="css/main.css">
</head>
<body>

</body>
</html>

You'll notice that we're referencing a css/main.css file, which doesn't yet exist. Create a new folder css/ and a main.css inside of it, with the following contents:

    html,body {
        margin:0;
        background:lightgray;
        font-family: Arial;
    }

    h1 {margin:0;}

    .container {
        width: 350px;
        padding: 2em;
        background:white;
        border-radius: 8px;
        margin: 10% auto;
    }

    .txtfld {
        width: calc(100% - 2em);
        padding:1em;
        margin-top: 1em;
    }
    .btn {
        width:100%;
        background:#00c3ff;
        color:white;
        margin-top:2em;
        border:none;
        border-radius:5px;
        padding:1em;
        font-size:1.2em;
        cursor:pointer;
    }

    p {color:gray;}
    
    .msg {
        position: absolute;
        padding: .5em;
        background: rgba(0,0,0,.8);
        color: #fff;
        opacity: 0;
    }    

This is just some basic CSS styling that I'm not going to explain. Nothing too fancy is happening here.

Going back to our index.html file, to actually integrate Popmotion, we need to include it at the bottom just before the closing </body> tag:

    ...

    <script src="https://unpkg.com/popmotion/dist/popmotion.global.min.js"></script>
</body>

Note: If you were using something like React or Angular, you would import Popmotion via:

// Imports the entire library
import { tween } from 'popmotion'

// Imports a specific subset of the library
import tween from 'popmotion/animations/tween';

Great! Popmotion is now integrated, but in order to use it, we need to add some HTML.

Adding some HTML

For this UI animation example, we'll construct a simple modal-style form for entering a name and email address.

Update the index.html file with the following:

<body>

    <div class="container">
        <h1>Fill it out</h1>
        <p>Please fill out the form below because that's what we really need you to do. Thanks.</p>
        <form>
            <span class="msg">Full name please!</span>
            <input type="text" placeholder="Name" class="txtfld">
            <input type="text" placeholder="Email Address" class="txtfld">

            <input type="submit" value="Enter info" class="btn">
        </form>
    </div>


    <script src="https://unpkg.com/popmotion/dist/popmotion.global.min.js"></script>
</body>

Save it and open up the index.html file in the browser. The result should look like this:

Great, so, how do we animate this? Let's give it a shot!

Creating Basic Animations in JavaScript with Popmotion

Let's say for instance, that we want our modal here to grow and fade in. To do this, we first have to gain access to the .container class through JavaScript. We'll also create constants for two other elements that we will animate later on.

In index.html add the following code just underneath our first <script src tag as shown:

...

<script src="https://unpkg.com/popmotion/dist/popmotion.global.min.js"></script>

<script>
    const container = popmotion.styler(document.querySelector('.container'));
    const formElements = document.querySelector('.inner');
    const msgPop = popmotion.styler(document.querySelector('.msg'));
</script>

Now, we will use the tween method from the Popmotion API docs to establish a from and to value for scale:

const container = popmotion.styler(document.querySelector('.container'));
const formElements = document.querySelector('.inner');
const msgPop = popmotion.styler(document.querySelector('.msg'));

popmotion.tween({ 
    from: { 
        scale: .7
    },
    to: { 
        scale: 1
    },
    duration: 1000
})
.start(container.set);

If you save this and refresh the browser, the result should show the form container (and the form itself) growing from 70% of its original size to 100%, over a duration of 1 second.

Simple, huh?!

Animating Multiple Properties

What if we wanted the modal to also fade in from 0% opacity to 100%? Simple:

            from: { 
                scale: .7, 
                opacity: 0 
            },
            to: { 
                scale: 1, 
                opacity: 1 
            },

You simply comma separate the property value pairs within the object. Now, this will fade in the the modal.

Let's add a third property that will move the modal down on the Y axis:

            from: { 
                scale: .7, 
                opacity: 0,
                y: -300
            },
            to: { 
                scale: 1, 
                opacity: 1,
                y: 0
            },

Creating Stagger Animations in JavaScript with Popmotion

Let's say that we want the individual form elements to also animate. To do that, we can create a stagger animation!

Looking at the Popmotion Home Page, under the Stagger animation example, we can see the code used to create an impressive stagger animation.

Underneath our .tween().start(); line, paste the following:

const stylers = Array
  .from(formElements.children)
  .map(popmotion.styler); 
        
const animations = Array(stylers.length)
  .fill(popmotion.spring({ from: 100, to:  0 }));

popmotion.stagger(animations, 100)
  .start((v) => v.forEach((x, i) => stylers[i].set('x', x)));

First, we're creating an array from the HTML elements inside of the .inner class.

Then, we define an animation for each array element using .fill(). In this case, we're going to create a .spring animation.

Then, we use .stagger() while passing in animations in the first argument, and the time between each animation 100ms. The stagger animation is started with the .start() method, which iterates over the animations array via .forEach(). It takes the values x, and .sets the x property to the values 100 and 0 to each HTML child element of .inner.

If you refresh, you will see the new stagger animation!

If you want the animation to occur on the Y axis, simply change:

// From
... stylers[i].set('x', x)));

// To
... stylers[i].set('y', x)));

Wala!

Starting Animations when others are finished

Each Popmotion .action (which, includes animations) provides a complete object. In other words, once an animation is finished, we can make stuff happen.

Let's make a little message appear when our initial animations are completed, notifying the user that they need to enter their full name.

To do this, we need to make a couple adjustments to our existing code.

First, we're going to remove .start(container.set) and bind our tween to a constant:

const myAnim = popmotion.tween({ 
    from: { 
        scale: .7, 
        opacity: 0,
        y: -300
    },
    to: { 
        scale: 1, 
        opacity: 1,
        y: 0
    },
    duration: 1000
})

Just underneath this, we're going to create a secondary animation that uses keyframes to create a more elaborate sequence of tween animations. This will be placed on our message popup, which will make it fade in and move along the Y axis: (you can put this underneath the code above)

        const myAnim2 = popmotion.keyframes({ 
            values: [
                { y: -50, opacity: 0 },
                { y: -20, opacity: 1 },
                { y: -20, opacity: 1 },
                { y: 0, opacity: 0 },
            ],
            times: [0, .2,.8, 1],
            duration: 3000
        })

To start the first animation, we simply call myAnim.start() and inside of the argument, we place an object with update set to container.set and complete which will start our second animation in the same manner:

        myAnim.start(
        {
            update: container.set,
            complete: () => { myAnim2.start(msgPop.set) }
        });

Great! Now, if you refresh, you will notice that our second animation begins after the first animation completes!

Here is the full code for the JavaScript section:

    <script>
        const container = popmotion.styler(document.querySelector('.container'));
        const formElements = document.querySelector('.inner');
        const msgPop = popmotion.styler(document.querySelector('.msg'));

        const myAnim = popmotion.tween({ 
            from: { 
                scale: .7, 
                opacity: 0,
                y: -300
            },
            to: { 
                scale: 1, 
                opacity: 1,
                y: 0
            },
            duration: 1000
        })

        const myAnim2 = popmotion.keyframes({ 
                    values: [
                        { y: -50, opacity: 0 },
                        { y: -20, opacity: 1 },
                        { y: -20, opacity: 1 },
                        { y: 0, opacity: 0 },
                    ],
                    times: [0, .2,.8, 1],
                    duration: 3000
                })

        myAnim.start({
            update: container.set,
            complete: () => { myAnim2.start(msgPop.set) }
        });


        const stylers = Array
        .from(formElements.children)
        .map(popmotion.styler); 
                
        const animations = Array(stylers.length)
        .fill(popmotion.spring({ from: 100, to:  0 }));

        popmotion.stagger(animations, 100)
        .start((v) => v.forEach((x, i) => stylers[i].set({'y': x})));

    </script>

Conclusion

We've just scratched the surface of what Popmotion JavaScript Animation can do. So, I hope you experiment more with this great framework!


Share this post




Say something about this awesome post!