Web Animations:

From Disney to SASS

@opherv / JSConfBP / Oct 2017

slides.com/opherv/jsconfbp2017

Blizzard

Art by DarrenGeers

@opherv

Hi! I'm Opher

I'm a creative developer at Eko

 

The Lion King (1994)

@opherv

@opherv

@opherv

@opherv

01  Squash and Stretch

02  Anticipation

03  Staging

04  Straight Ahead Action and Pose to Pose

05  Follow Through and Overlapping Action

06  Slow In and Slow Out

07  Arc

08  Secondary Action

09  Timing

12  Appeal

10  Exaggeration

11  Solid drawing

05  Follow Through and Overlapping Action

@opherv

@opherv

@opherv

@opherv

@opherv

@opherv

@opherv

What are we making?

Animation specs:

Four circles

 

Total Iteration time:  1 second


Circle moment time: 0.5 seconds

 

Circle stagger time: 0.15 seconds

@opherv

Our options

 Web Animation API

@opherv

Implementation 1

@opherv

Pros

Good performance across devices (GPU accelerated *)

Cons

Limited features /
complex animations are tricky

Defined using CSS

No dynamic animations

Hard to debug

CSS Animation - quick recap

@keyframes move {
  0%   { transform: translateX(0); }
  25% { transform: translateX(100px); }
  100% { transform: translateX(400px); }
}

span{
    animation: move 2s infinite;
}

Let's add animation-delay

hmm... what just happened?

animation-delay affects only the start delay. It doesn't affect animation repeats!

@opherv

Making sense of it all

0s = 0%
0.3s = 0.3 / 1s * 100 =  30%
0.8s = (0.3 + 0.5) / 1s * 100 = 80%
1s = 100%
@keyframes circle2{
  0%{ transform: translateX(0); }
  ???% { transform: translateX(0); }          
  ???% { transform: translateX(60px); }          
  100% { transform: translateX(60px); }     
}

The solution

@mixin createCircleAnimation($i, $animTime, $totalTime, $delay){      
      @include keyframes(circle#{$i}){
          0%, #{($i * $delay)/$totalTime * 100}% {     
            @include transform(translateX(0));            
          }          
          #{($i * $delay + $animTime)/$totalTime * 100}%, 100% {     
            @include transform(translateX(60px));            
          }          
        }      
}

$animTime: 0.5s;
$totalTime: 1s;
$staggerTime: 0.15s;

@for $i from 0 through 3 {
 @include createCircleAnimation($i, $animTime, $totalTime, $staggerTime); 
 span:nth-child(#{($i + 1)}){
 animation: circle#{(3 - $i)} $totalTime infinite;
 left: #{$i * 60 - 60 }px;
 }
}

mixin

@mixin createCircleAnimation($i, $animTime, $totalTime, $delay){      
      @include keyframes(circle#{$i}){
          0%, #{($i * $delay)/$totalTime * 100}% {     
            @include transform(translateX(0));            
          }  
        
          #{($i * $delay + $animTime)/$totalTime * 100}%, 100% {     
            @include transform(translateX(60px));            
          }          
        }      
}

usage

$animTime: 0.5s;
$totalTime: 1s;
$staggerTime: 0.15s;

@for $i from 0 through 3 {
 @include createCircleAnimation($i, $animTime, $totalTime, $staggerTime); 
 
  span:nth-child(#{($i + 1)}){
      animation: circle#{(3 - $i)} $totalTime infinite;
      left: #{$i * 60 - 60 }px;
 }
}

<-- Why I can't work from home

@opherv

Implementation 2

@opherv

Pros

Great, robust API

Cons

Requires loading an extra lib

Dynamic animations

Handles browser inconsistencies

JS is implementation-sensitive

Some advanced features cost $

@opherv

Which one to use?

Thanks!

@OpherV

opherv.com

Web Animation: from Disney to SASS

By Opher Vishnia

Web Animation: from Disney to SASS

  • 2,204