đź›  Modal: Animating the waving hand

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

đź›  Modal: Animating the waving hand

You’ll learn to animate the waving hand in this lesson.

Wave hand animation.

Don’t be scared of the animation. It might look complicated, but it’s quite easy once you know what to do.

You need to see there are two parts to the waving hand animation.

  1. The initial zooming part
  2. The actual waving part

CSS Transition or CSS Animation

The wave-hand animation (zoom + wave) is too complicated for a CSS Transition. We need to use a CSS Animation.

The zooming part

Two things happen during the zooming part.

  1. The hand turns opaque (from invisible to visible)
  2. The hand pops out (from small to big)

To make the hand turn opaque, we use opacity. To make the hand zoom up, we use scale.

/* Makes waving hand zoom out */
@keyframes zoom {
  0% {
    transform: scale(0.25);
    opacity: 0;
  }

  100% {
    transform: scale(1);
    opacity: 1;
  }
}

Once you’ve built the zoom animation, add it to the waving hand.

.wave-hand {
  /* This is the backwards cubic-bezier curve */
  animation: zoom 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}

We want .wave-hand to zoom in only when we open the modal. But at this stage, when we’re building the animation, it helps to see the animation right away.

We will add the modal-is-open class to <body> to help us see the animation.

<body class="modal-is-open"><!-- ... --></body>
Wave hand zooms out and turns opaque.

The waving part

The waving part feels complicated. When you make anything that feels complicated, you want to focus only on that part.

To focus only on that part, you extract that part and work on it elsewhere. This is called creating a reduced case.

I’ve prepared a CodePen for you to play around with the wave part. Go ahead and click on this link to get started.

To create wave animation, you need to know where the waving hand moves to. Our hand moves to these six points:

  1. Begins straight upright
  2. Rotates to its left (your right)
  3. Rotates to its right (your left)
  4. Rotates to its left again
  5. Rotates to its right again
  6. Goes back to the starting position

You can say that these 6 points are “snapshots” in the animation. Once you get these six points right, the rest of the animation follows through easily.

6 points of wave-hand animation

Since each snapshot takes up the same amount of time, you can split the @keyframes points evenly into 6 steps (including 0%).

@keyframes wave {
  0% { /* Start at center */ }
  20% { /* Rotate to its left */ }
  40% { /* Rotate to its right */ }
  60% { /* Rotate to its left */ }
  80% { /* Rotate to its right */ }
  100% { /* Back to center */ }
}

For the waving animation, the hand rotates by 15 degrees in each wave. To rotate clockwise, you set rotate to 15 degrees. To rotate anti-clockwise, you set rotate to -15 degrees.

@keyframes wave {
  0% { transform: rotate(0); }
  20% { transform: rotate(15deg); }
  40% { transform: rotate(-15deg); }
  60% { transform: rotate(15deg); }
  80% { transform: rotate(-15deg); }
  100% { transform: rotate(0); }
}

.wave-hand {
  animation: wave 1s ease-in-out;
}
<!-- Remember to add the wave-hand class to your HTML! -->
<svg class="wave-hand" width="112" height="139" viewBox="0 0 112 139"><use xlink:href="images/sprite.svg#wave-hand" /></svg>
The hand waves! But...
The hand waves! But...

Whoa! The animation looks weird. It rotates around the middle of the hand. That’s not how you normally wave!

You want the hand to rotate about the bottom center part so the animation looks natural. To do so, you change transform-origin (which tells CSS where to animate from) to bottom center.

.wave-hand {
  transform-origin: bottom center;
  animation: wave 1s ease-in-out;
}
The hand waves correctly now!
The hand waves correctly now!

Much better!

Next, we combine the zoom animation with the wave animation together in the wave-hand selector.

Since zoom comes first, let’s put zoom before wave in the animation property. We’ll add a slight delay to the wave animation to make sure it comes after zoom.

.wave-hand {
  transform-origin: bottom center;
  animation: zoom 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28),
    /* creates a delay for the wave animation. Experiment with the delay value here! */
    wave 1s 0.55s ease-in-out;
}
Wave hand animation.

Wave hand when opening the modal

We want the hand to wave when we open the modal. To do this, add the animation only when modal-is-open is present on <body>.

(Remember to remove modal-is-open from your HTML).

.wave-hand {
  /* remove animation from here */
}

.modal-is-open .wave-hand {
  transform-origin: bottom center;
  animation: zoom 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28),
    wave 1s 0.55s ease-in-out;
}
Wave hand animation.

And we’re done!