Praktische

 Web Animation

lisilinhart.info

CSS

Transitions

Animation

Transform

Easings

SVG

CSS

GSAP

WAAPI

.animate()

Libraries

controls & callbacks

Support

Codepen

CSS Animation & Transitions

CSS Animation & Transitions

+

-

  • lade Animationen
  • :hover, :focus; :active, :target
  • Übergangsanimation
  • wiederverwendbare keyframes
  • Adaption in media queries
  • gute Performance

 

  • begrenzte Events
  • nicht dynamisch *
  • keine separaten transform properties *
  • nicht ideal für komplexe Animations / Timelines

CSS Transitions

.foo {
    transition: <property> <duration> <timing-function> <delay>;
}

CSS

CSS Transitions

.color-delay {
  color: black;
  transition-property: color;
  transition-duration: 3s;
  transition-timing-function: ease-in-out;
  transition-delay: 2s;
}
.color-delay {
  color: black;
  transition: color 3s ease-in-out 2s;
}
.color-delay:hover {
  color: teal;
}

CSS

CSS

CSS

CSS Transitions

.color-delay {
  color: black;
  transition-property: color;
  transition-duration: 3s;
  transition-timing-function: ease-in-out;
  transition-delay: 2s;
}
.color-delay {
  color: black;
}
.color-delay:hover {
  color: teal;
  transition: color 3s ease-in-out 2s;
}

CSS

CSS

CSS

nicht hier definieren

CSS Transitions

.color-delay {
  color: black;
  transition-property: color;
  transition-duration: 3s;
  transition-timing-function: ease-in-out;
  transition-delay: 2s;
}
.color-delay {
  color: black;
  transition: color 3s ease-in-out 2s;
}
.color-delay:hover {
  color: teal;
  transition: color 3s ease-in-out 2s;
}

CSS

CSS

CSS

immer im default definieren

CSS Transitions

 

Multiple Transitions

.foo {
    transition: color 1s ease-in 1s, background 2s ease-out;
}
.foo {
    transtion-property: color, background;
    transition-duration: 1s, 2s;
    transition-timing-function: ease-in, ease-out;
    transition-delay: 1s, 0;
}

CSS

::before & ::after

  • pseudo elements  erlauben Einfügen von CSS Content vor oder nach einem DOM Element

  • ideal für Animation, da keine unnötigen HTML Elemente erzeugt werden

  • die content: "";  property muss definiert sein

  • kein html einfügen: content: "<h1>big text</h1>";
                  

 

h1::before {
  content: "🐼";
}

h1::after {
  content: "🚲";
}
<h1>Lieblingsdinge</h1>

Lieblingsdinge

🐼

🚲

CSS

HTML

Die Transform Property

Es gibt 4 Dinge, die der Browser performant animieren kann

  • Position - transform: translate(...);
  • Skalierung - transform: scale(..);
  • Rotation - transform: rotate(..);
  • Opacity - opacity: 0;
.foo {
    transform: translateX(-20px);
}

CSS

            translateX(-20px)
        
            rotate(25deg)
        
            scale(0.5)
        
            skewY(-20deg)
        
rotateX(50deg)

Die Transform Property

Transform Origin Property

.foo {
    transform-origin: 100% 50%;
}
  • Position von wo der Transform ausgehen soll

  • Default is 50% 50%

CSS

Transform Origin

Multiple Transforms

Ein  Beispiel

Ein  Beispiel

  • einen Button der Transforms auf dem :before oder :after Element animiert

  • die Animation soll beim :hover Event passieren

  • Animation soll über die CSS transition property geregelt werden.

transition: transform 300ms cubic-bezier(0.470, 0.000, 0.745, 0.715);

CSS Animation

CSS Animation

  • looping
  • mehrere states in einer Animation
  • mehr Kontrolle & Optionen als Transitions
  • z.B. für loading spinners, Icon Animationen, komplexere :hover Animationen

CSS Animation

  1. keyframes: Stadien & Stil der Animation
  2. animation property: wie es animiert ist (z.B. speed, delay, ..)

besteht stets aus:

CSS Keyframes

@keyframes fadeInOut {
  0% {
   opacity: 0;
 }
  50% {
   opacity: 1;
 }
 100% {
   opacity: 0;
 }
}
.foo {
  opacity: 0;
  animation: fadeInOut 2s;
}

@keyframes fadeInOut {
  50% {
   opacity: 1;
 }
}
 
@keyframes fadeOut {
 from {
   opacity: 0;
 }
 to {
   opacity: 1;
 }
}
 

CSS

CSS

CSS

CSS Animations Property

.foo {
    animation: <name> <duration> <timing-function> <delay> 
                <iteration-count> <direction> <fill-mode> <play-state>;
}
.foo {
    animation: bounce 3s linear .2s infinite alternate forwards paused;
}

CSS

Multiple Animations

.foo {
    animation: slideIn 2s, fadeIn 1.75s;
}

CSS

Praktisches Beispiel

Praktisches Beispiel

  • die Box soll im Uhrzeigersinn in dem Container animiert werden
  • hierfür muss transform: translate(<x>, <y>) verwendet werden
  • die Distanzen können in px (250px) oder in Prozent (100%) angegeben werden.
  • Die Box muss jeweils um 200% bewegt werden, da sie 1/3 so groß ist wie die Umrandung
  • versuchen Sie ein anderes easing in .inner-box hinzuzüfgen

Bessere Easings

Praktisches Beispiel

Praktisches Beispiel

  • den Text nur mit CSS & ev. SASS animieren
  • SASS Schleifen vereinfachen die Animation für jeden Buchstaben
    • SASS Schleifen zb. dafür verwenden ein animation-delay für jeden Buchstab zu definieren
  • wenden Sie mindestens die folgenden zwei Animationen auf jeden Buchstaben mit Hilfe von @keyframes an:

        * eine, die den Buchstaben mit transform: translate()
        * eine, die die Farbe der Buchstaben ändert mit color

Tipps

@for $i from 1 to $letter-count {
	span:nth-child(#{$i}) {
		animation-delay:  (0.2s * $i);
	}
}
@keyframes colorChange {
	50% {
		color: #FFBD39;
	}
}
animation: colorChange 2.5s ease-in-out infinite forwards;

Bessere Easings

CSS  Zusammenfassung

Transitions

  • single state Änderungen
  • :hover, :focus; :active, :target
  • z.B. buttons, links, etc

 

Animation

  • looping
  • mehrere Stadien in der Animation
  • mehr Kontrolle & Möglichkeiten wie transitions
  • z.B. loading spinners, icon animation

 

gut für

  • animierte Interaktionen
  • simple Animationen
  • gute Performance ohne externe Libraries oder Javascript Blocking

nicht so gut für

  • Timelines und Chainen von mehreren Animation (mehr als 4)
  • wenn sich die Animation dynamisch während der Runtime verändenr soll (z.B. wegen user input)
  • wenn Physics oder komplexe Easings benötigt werden

CSS  Zusammenfassung

Pause

SVG

Wieso SVG?

  • skalierbar
  • responsive
  • accessible
  • kleine Dateigröße
  • weniger HTTP requests
  • über CSS stylebar & animierbar

SVG Elemente

 <circle 
    cx="100"
    cy="100"
    r="80"
    fill="#4e9a06" />
<ellipse 
    cx="170"
    cy="43"
    rx="27"
    ry="15" 
    fill="#73d216"
/>
<rect
    x="80"
    y="100"
    width="90"
    height="90" 
    fill="#204a87" />
<path 
    d="M 149,109 L 149,127 ... z"
    fill="#edd400" />
<polygon points="0,100 50,25 50,75 100,0" />

SVG Path

SVG Path

SVG Viewbox

 <svg viewBox="0 0 450 100">...</svg>
 svg { width: 450px; }

 <svg viewBox="0 0 450 100">...</svg>
 svg { width: 200px; }

SVG Viewbox

SVG erstellen

  • Illustrator
  • Sketch
  • Inkscape
  • DrawSVG

 

export Optionen des Editors verwenden!

SVG exportieren

SVG exportieren

SVGs optimieren

SVGs optimieren

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In
 . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="218.8px" height="87.1px" viewBox="0 0 218.8 87.1" 
enable-background="new 0 0 218.8 87.1" xml:space="preserve">
<g>
	<path fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" 
d="M133.1,58.2c0,0,12.7-69.2,24.4-47.5c0,0,4.1,8.6,9.5,0.9
		c0,0,5-10,10.4,0.9c0,0,12.2,32.6,13.6,43c0,0,39.8,5.4,15.8,
15.4c-13.2,5.5-53.8,13.1-77.4,5.9C129.5,76.8,77.5,61.4,133.1,58.2z"
		/>
	<path fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" 
d="M6.7,61.4c0,0-3.3-55.2,20.8-54.8s-7.2,18.1,4.1,29.9
		s8.6-31.2,32.1-15.8S86.7,41,77.2,61.8C70.4,76.8,76.8,79,37.9,
79c-0.4,0-0.9,0.1-1.3,0.1C9,81,40.1,58.7,40.1,58.7"/>
</g>
</svg>

SVGs optimieren

<svg viewBox="0 0 218.8 87.1">
  <g fill="none" stroke="#000">
    <path d="M7.3 75L25.9 6.8s58.4-6.4 33.5 13-41.1 32.8-11.2 30.8h15.9v5.5s42.6 18.8 0 20.6" />
    <path d="M133.1 58.2s12.7-69.2 24.4-47.5c0 0 4.1 8.6 9.5.9 0 0 5-10 10.4.9 0 0 12.2 
32.6 13.6 43 0 0 39.8 5.4 15.8 15.4-13.2 5.5-53.8 13.1-77.4 5.9.1 0-51.9-15.4 3.7-18.6z" />
  </g>
</svg>

SVG Code

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 65 65">
  <circle data-name="outer-fade" cx="32.5" cy="32.5" r="32.5" fill="#489ba9"/>
  <circle data-name="outer-fill" cx="32.5" cy="32.5" r="32.5" fill="#fff"/>
  <path data-name="outer-stroke" d="M32.5 2A30.5 30.5 0 1 1 2 32.5 30.5 30.5 0 0 1 32.5 2m0-2A32.5 32.5 0 1 0 65 32.5 32.5 32.5 0 0 0 32.5 0z" fill="#254355"/>
  <path data-name="center-star-fill" d="M22.1 46.9a.4.4 0 0 1-.4-.5l2-11.3-8.3-8.1a.4.4 0 0 1 .2-.6L27 24.7l5.2-10.4a.4.4 0 0 1 .6 0L38 24.7l11.4 1.7a.4.4 0 0 1 .2.6l-8.2 8 2 11.5a.3.3 0 0 1-.2.3.3.3 0 0 1-.4 0l-10.3-5.3-10.2 5.3a.3.3 0 0 1-.2 0z" fill="#3c3c3c"/>
  <path data-name="center-star-stroke" d="M22.1 46.9a.4.4 0 0 1-.4-.5l2-11.3-8.3-8.1a.4.4 0 0 1 .2-.6L27 24.7l5.2-10.4a.4.4 0 0 1 .6 0L38 24.7l11.4 1.7a.4.4 0 0 1 .2.6l-8.2 8 2 11.5a.3.3 0 0 1-.2.3.3.3 0 0 1-.4 0l-10.3-5.3-10.2 5.3a.3.3 0 0 1-.2 0zM18 27.3l7.1 7a.3.3 0 0 1 .1.3l-1.7 9.8 8.8-4.7a.4.4 0 0 1 .4 0l8.8 4.7-1.7-9.8a.3.3 0 0 1 0-.3l7.2-7-9.8-1.4a.3.3 0 0 1-.3-.2l-4.4-9-4.4 9a.3.3 0 0 1-.3.2z" fill="#3c3c3c"/>
  <path data-name="star-10" d="M19.4 19.5c-.3 0-.2-1-1-2s-2-.8-2-1 1.2-.3 2-1 .9-2 1.2-2 .2 1.1 1 2 2 .8 2 1.1-1.2.2-2 1-.9 2-1.2 2z" fill="#fd7865"/>
  <path data-name="star-9" d="M9.4 27.5c-.2 0-.1-.7-.6-1.3s-1.3-.5-1.3-.8.7-.1 1.3-.6.5-1.4.8-1.3.1.7.6 1.3 1.4.5 1.3.8-.7.1-1.3.6-.5 1.3-.8 1.3z" fill="#489ba9"/>
  <path data-name="star-8" d="M13.4 41.5c-.3 0-.2-1-1-2s-2-.8-2-1 1.2-.3 2-1 .9-2 1.2-2 .2 1.1 1 2 2 .8 2 1.1-1.2.2-2 1-.8 2-1.2 2z" fill="#fd7865"/>
  <path data-name="star-7" d="M18.4 53.5c-.2 0-.1-.7-.6-1.3s-1.4-.5-1.3-.8.7-.1 1.3-.6.5-1.3.8-1.3.1.7.6 1.3 1.3.5 1.3.8-.7.1-1.3.6-.5 1.3-.8 1.3z" fill="#fcc14c"/>
  <path data-name="star-6" d="M32.4 55.5c-.3 0-.2-1-1-2s-2-.8-2-1 1.2-.3 2-1 .9-2 1.2-2 .2 1.1 1 2 2 .8 2 1.1-1.2.2-2 1-.9 2-1.2 2z" fill="#489ba9"/>
  <path data-name="star-5" d="M46.4 52.5c-.2 0-.1-.7-.6-1.3s-1.3-.5-1.3-.8.7-.1 1.3-.6.5-1.3.8-1.3.1.7.6 1.3 1.3.5 1.3.8-.7.1-1.3.6-.5 1.3-.8 1.3z" fill="#fd7865"/>
  <path data-name="star-4" d="M52.4 40.5c-.3 0-.2-1-1-2s-2-.8-2-1 1.2-.3 2-1 .9-2 1.2-2 .2 1.1 1 2 2 .8 2 1.1-1.2.2-2 1-.8 2-1.2 2z" fill="#fcc14c"/>
  <path data-name="star-3" d="M56.4 26.5c-.2 0-.1-.7-.6-1.3s-1.3-.5-1.3-.8.7-.1 1.3-.6.5-1.4.8-1.3.1.7.6 1.3 1.3.5 1.3.8-.7.1-1.3.6-.5 1.3-.8 1.3z" fill="#fd7865"/>
  <path data-name="star-2" d="M43.4 19.5c-.3 0-.2-1-1-2s-2-.8-2-1 1.2-.3 2-1 .9-2 1.2-2 .2 1.1 1 2 2 .8 2 1.1-1.2.2-2 1-.9 2-1.2 2z" fill="#489ba9"/>
  <path data-name="star-1" d="M31.4 10.5c-.2 0-.1-.7-.6-1.3s-1.4-.5-1.3-.8.7-.1 1.3-.6.5-1.4.8-1.3.1.7.6 1.3 1.3.5 1.3.8-.7.1-1.3.6-.5 1.4-.8 1.3z" fill="#fcc14c"/>
</svg>

Praktisches Beispiel

SVG + CSS ANIMATION = 😖

SVG & GSAP = ❤️

GSAP

GSAP Cheatsheet

GSAP Syntax

TweenLite.to("div", 2, { 
    scaleY:0.75, scaleX:1.25, y:100, opacity:0.75, ease:Elastic.easeOut 
});

GSAP Syntax

TweenLite.to("div", 2, { 
    scaleY:0.75, scaleX:1.25, y:100, opacity:0.75, ease:Elastic.easeOut 
});

Element Selektor

Dauer der Animation

CSS Attribute die animiert werden

Easing

GSAP Ease Visualizer

Stagger

TweenMax.staggerTo(".square", 2, {
    y:100, 
    backgroundColor:"#4f9d88", 
    ease:Elastic.easeOut
}, 0.05);

Timelines

  • eine Art Animationssequenz
  • mehrere Animationen nacheinander abspielen
  • Animationen aufeinander abstimmen
  • Gruppieren von Animationen
  • gesamt Animationsequenz schneller oder langsamer machen

Timelines

const tl = new TimelineLite();

tl.to('.square--one', 1, { y: 100, ease: Back.easeOut })
  .to('.square--two', .8, { rotation: '30deg', backgroundColor: 'teal', ease: Elastic.easeOut })
  .to('.square--three', .5, { scale: 0.5, borderColor: '#2F3C4F', ease: Bounce.easeOut });

Timeline Syntax

const tl = new TimelineLite();

tl.set('.square--one', { y: -200 });

tl.to('.square--one', 1, { y: 100 })
  .to('.square--two', 0.8, { rotation: '30deg' })
  .to('.square--three', 0.5, { scale: 0.5 }, '-=0.4')
  .fromTo('.square--four', 0.5, { scale: 0 }, { scale: 0.5 }, '+=0.25')
  .to('.square--five', 0.5, { rotation: '120deg' }, { scale: 0.5 }, 0.2);

neue Timeline

startet wenn die vorige Animation fertig ist

setzt Elementstyling bevor Animation startet

startet 0.4s bevor die vorige Animation fertig ist

startet 0.25s nachdem die vorige Animation fertig war

startet 0.2s nach Beginn der Timeline

Timeline Syntax

TweenMax.to(obj, 1, {x:100});
  • TweenMax.set()
  • TweenMax.to()
  • TweenMax.fromTo()
  • TweenMax.staggerTo()
  • TweenMax.staggerFromTo()
TweenMax.fromTo(element, 1, {x:0}, {x:100});
TweenMax.staggerTo(objects, 1, { y:"+=150", opacity:0 }, 0.2);
TweenMax.staggerFromTo(objects, 
                        1, 
                        {opacity:1}, 
                        {opacity:0}, 
                        0.2);
TweenMax.set(object, {x:100, y:50, opacity:0});

Praktisches Bespiel

Praktisches Bespiel

  • stagger auf die verschiedenen text elemente
  • durchgängige Animation auf die Blätter zb.

Andere SVG Libraries

SVG Accessbility

<svg aria-labelledby="title" 
  id="svg" 
  role="presentation" 
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 765 587">

<title id="title" 
  lang="en">
  Icons that illustrate Global Warming Solutions
</title>

Title for elements in the SVG DOM

Role to let the screen reader know whether to traverse

SVG Animations Collections

Web

Animations

API

Web Animations API

  • vollständige Animation in JS
  • mehr Kontrolle über Animationen
  • ideal für dynamische, reaktive Animationen
  • in Kombination mit JS Events
  • Callback Functions
  • Grouping & Timing

Web Animations API

  1. keyframes object / array: Frames der Animation
  2. timing object: Art der Animation (e.g. Dauer, Delay, ..)

Animation besteht aus:


    el.animate(<keyframes>, <timing object>);

WAAPI Keyframes

2 Möglichkeiten

{
  opacity: [ 0, 1 ],          // [ from, to ]
  color:   [ "#fff", "#000" ] // [ from, to ]
}
[ 
  { // from
    opacity: 0,
    color: "#fff"
  }, 
  { // to
    opacity: 1,
 ​   color: "#000"
  }
]

object

array

JS

JS

WAAPI Timing Object

{
    duration: 2000, // milliseconds
    iterations: 1, // or Infinity
    direction: 'normal', // 'alternate', 'reverse', 'alternate-reverse'
    fill: 'forwards', // 'backwards', 'both', 'none', 'auto'
    delay: 0, // milliseconds
    endDelay: 0, // milliseconds
    easing: 'linear', // 'ease', 'ease-in-out', 'ease-in', ...
 }

JS

.animate()

const foo = document.querySelector(".foo");

foo.animate(<keyframes array>, <timings object>);

JS

.animate()

const foo = document.querySelector(".foo");

foo.animate([
    { transform: 'scale(0)', opacity: 0 },
    { transform: 'scale(1)', opacity: 1 },
  ], {
    duration: 2000, 
    easing: 'ease-in-out', 
    iterations: 1, 
    direction: 'normal', 
    fill: 'forwards' 
  }
);

JS

controls

const animation = element.animate(/* animation */);
console.log(animation.playState); //"running"

animation.pause(); //"paused"
animation.play();  //"running"
animation.cancel(); //"idle"... jump to original state
animation.finish(); //"finished"...jump to end state
animation.reverse(); // play animation in reverse

animation.playbackRate = 1.5; // play faster

callbacks

const animation = element.animate(/* animation */);

animation.onfinish = function() {
  console.log("Animation finished");
};

// remove element from DOM
animation.oncancel = animation.effect.target.remove();

.animate()

.animate()

const keyframes = [
    { transform: 'translateY(0%)', easing: 'ease-in', offset: 0 },
    { transform: 'translateY(500%)', easing: 'ease-out', offset: .33 },
    { transform: 'translateY(420%)', easing: 'ease-in', offset: .5 },
    { transform: 'translateY(500%)', easing: 'ease-out', offset: .66 },
    { transform: 'translateY(460%)', easing: 'ease-in', offset: .82 },
    { transform: 'translateY(500%)', easing: 'ease-out', offset: .92 },
    { transform: 'translateY(480%)', easing: 'ease-in', offset: .97 },
    { transform: 'translateY(500%)', easing: 'ease-out', offset: 1 },
];
const timing = {
    duration: 2000,
    iterations: 1, 
    direction: 'normal', 
    fill: 'forwards',
    delay: 0, 
    endDelay: 0,
    easing: 'linear', 
};
const apple = document.querySelector(".apple");
const animation = apple.animate(keyframes, timing);

.animate()

tree.addEventListener('click', () => {
    animation.currentTime = 0;
    animation.play();
});
apple.addEventListener('click', () => {
    animation.playbackRate += 0.2;
});

Praktisches Beispiel

  • verschiedene Elemente in AnimateIn Funktion animieren
  • verschiedene Elemente in AnimateOut Funktion animieren
  • callbacks verwenden

Praktisches Beispiel

player.onfinish = function() {
  console.log(player.currentTime); // 3500
};
background.animate({
        transform: ['scaleY(0)', 'scaleY(1)'],
},{
      duration: 700,
      fill: 'both',
      easing: sineInOut,
});

cssreference.io/animations/

developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API

CSS

vs

WAAPI

CSS

WAAPI

CSS

WAAPI

  • vorkompiliert
  • statische Animationen
  • :hover, :focus
  • deklarativ
  • simpel
  • keine JS-Blockierung
  • Sequenzierung
  • Controls & Callback
  • document.timeline
  • Hardwarebeschleunigung
  • wird eine native Alternative für Animation sein
  • mehr Kontrolle als reines CSS

cross-browser compatiblity & SVG

browser renderer & optimization

native Animation vs. externe Libraries

WAAPI vs Libraries

small size vs. fancy plugins

WAAPI vs Libraries

Browser

Support

Can I Use

Just Animate

Praktische Webanimation

By Lisi Linhart

Praktische Webanimation

Workshop Ditact Salzburg

  • 329