Composable Animation

A presentation at Clarity in December 2018 in 5000 Estate Enighed, Independence, KS 67301, USA by Sarah Drasner

Slide 1

Slide 1

Composable animation

Slide 2

Slide 2

The Goal

Slide 3

Slide 3

Communicating @sarah_edo

Slide 4

Slide 4

? @sarah_edo

Slide 5

Slide 5

Happiness sadness Fear curiosity @sarah_edo

Slide 6

Slide 6

Happiness sadness Fear curiosity @sarah_edo

Slide 7

Slide 7

@sarah_edo

Slide 8

Slide 8

@sarah_edo

Slide 9

Slide 9

Anything can happen

Slide 10

Slide 10

SARAH DRASNER @SARAH_EDO

Slide 11

Slide 11

Branding And personality

Slide 12

Slide 12

@sarah_edo

Slide 13

Slide 13

dribbble.com/leoleung @sarah_edo

Slide 14

Slide 14

tympanus.net/Development/ImageRevealHover/ @sarah_edo

Slide 15

Slide 15

Easing

Slide 16

Slide 16

Slide 17

Slide 17

codepen.io/sdras/pen/pyedJE css-tricks.com/comparison-animation-technologies/

Slide 18

Slide 18

@sarah_edo

Slide 19

Slide 19

codepen.io/sdras/pen/qOdwdB @sarah_edo

Slide 20

Slide 20

Create beautiful defaults (from THE Jina!) @sarah_edo

Slide 21

Slide 21

@sarah_edo

Slide 22

Slide 22

@sarah_edo

Slide 23

Slide 23

Chris Gannon gannon.tv/products/download-dot-bounce @sarah_edo

Slide 24

Slide 24

codepen.io/sdras/pen/LEorev @sarah_edo

Slide 25

Slide 25

Having an opinion @sarah_edo

Slide 26

Slide 26

dribbble.com/rally @sarah_edo

Slide 27

Slide 27

dribbble.com/outcrowd @sarah_edo

Slide 28

Slide 28

dribbble.com/uigreat @sarah_edo

Slide 29

Slide 29

dribbble.com/Yar_Z @sarah_edo

Slide 30

Slide 30

dribbble.com/advancedgroup @sarah_edo

Slide 31

Slide 31

codepen.io/sdras/pen/gWWQgb @sarah_edo

Slide 32

Slide 32

Look around you Study reality

Slide 33

Slide 33

Unpopular opinion: Stop using material design as your motion design

Slide 34

Slide 34

codepen.io/sdras/pen/JbaGwg @sarah_edo

Slide 35

Slide 35

“It’s important to define your audience for your documentation early.” Val head, designing interface animation

Slide 36

Slide 36

Have a bdfl ... but also support @sarah_edo

Slide 37

Slide 37

Composing Creating Beautiful Defaults @sarah_edo

Slide 38

Slide 38

codepen.io/sdras/pen/qqVrxy @sarah_edo

Slide 39

Slide 39

Timing Like h1, h2 //---timing ----// $class-slug: t !default; @for $i from 1 through 7 { .#{$class-slug}-#{$i} { animation-duration: 0.8 - (0.1s * $i); } } @sarah_edo

Slide 40

Slide 40

Easing Branded //---ease ----// $easein-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53); $easeout-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94); $easein-back: cubic-bezier(.57, .07, .6, 1.71); $easeout-back: cubic-bezier(0.175, 0.885, 0.32, 1.275); .entrance { animation-timing-function: $easeout-quad; } @sarah_edo

Slide 41

Slide 41

Animations Only what you need //animations @keyframes pop { 0% { transform: scale(0.9) translateZ(0); } 100% { transform: scale(1) translateZ(0); } } .pop { animation-name: pop; @extend .anim-fill-both; } @sarah_edo

Slide 42

Slide 42

@sarah_edo

Slide 43

Slide 43

@sarah_edo

Slide 44

Slide 44

@sarah_edo

Slide 45

Slide 45

<TransitionGroup> { this.state.shouldShowSoundwaves && <Soundwaves outTime={0.5} drawTiming={5} elTime={1} easing=‘Circ’ /> } </TransitionGroup> @sarah_edo

Slide 46

Slide 46

Vue Single File Components <template> <div> </div> </template> <script> export default { } </script> <style scoped> </style> @sarah_edo

Slide 47

Slide 47

Import Global Sass Files for Overarching Principles module.exports = { css: { loaderOptions: { sass: { data: @import "@/scss/_variables.scss"; } } } } css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/ @sarah_edo

Slide 48

Slide 48

@sarah_edo

Slide 49

Slide 49

<template> <svg @click="makeHeart" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 120 120" aria-labelledby="heartface" role="presentation"> ... </svg> </template> <script> import { TweenMax, TimelineMax, Sine } from ‘gsap' export default { methods: { makeHeart() { const tl = new TimelineMax() tl.add('start') ... } } } </script> github.com/sdras/vue-sample-svg-icons @sarah_edo

Slide 50

Slide 50

Responsive interactions Desktop and mobile compatible Zingtouch Hammer Draggable Flickity onMouseOver || onTouchStart @sarah_edo

Slide 51

Slide 51

Responsive consistency • SVG is great for responsive • Eases should stay the same, but timing can be adjusted • initial-scale=1.0 in the meta tag or device will wait 300ms • Larger touch-target, > 40px x 40px or use @media(pointer:coarse) 24ways.org/2016/animation-in-design-systems/ @sarah_edo

Slide 52

Slide 52

page transitions

Slide 53

Slide 53

@sarah_edo

Slide 54

Slide 54

Templates in the pages directory <nuxt-link to="/product">Product</nuxt-link> @sarah_edo

Slide 55

Slide 55

@sarah_edo

Slide 56

Slide 56

Transition hook already available name=“page" .page-enter-active, .page-leave-active { transition: all .25s ease-out; } .page-enter, .page-leave-active { opacity: 0; transform: scale(0.95); transform-origin: 50% 50%; } .page-enter-active, .page-leave-active { transition: all .25s ease-out; } .page-enter, .page-leave-active { opacity: 0; transform: scale(0.95); transform-origin: 50% 50%; } @sarah_edo

Slide 57

Slide 57

@sarah_edo

Slide 58

Slide 58

Js hooks export default { transition: { mode: 'out-in', css: false, enter (el, done) { let tl = new TimelineMax({ onComplete: done }), spt = new SplitText('h1', { type: 'chars' }), chars = spt.chars; TweenMax.set(chars, { transformPerspective: 600, perspective: 300, transformStyle: 'preserve-3d' }) } tl.add('start') tl.from(el, 0.8, { scale: 0.9, transformOrigin: '50% 50%', ease: Sine.easeOut }, 'start') ... tl.timeScale(1.5) @sarah_edo

Slide 59

Slide 59

@sarah_edo

Slide 60

Slide 60

Repo https://github.com/sdras/nuxt-type Demo https://nuxt-type.now.sh/ @sarah_edo

Slide 61

Slide 61

Native-like page transitions

Slide 62

Slide 62

@sarah_edo

Slide 63

Slide 63

@sarah_edo

Slide 64

Slide 64

@sarah_edo

Slide 65

Slide 65

In store/index.js import Vuex from 'vuex' const createStore = () =>" { return new Vuex.Store({ state: { page: 'index' }, mutations: { updatePage(state, pageName) { state.page = pageName } } }) } export default createStore @sarah_edo

Slide 66

Slide 66

In middleware/pages.js: export default function(context) { // go tell the store to update the page context.store.commit('updatePage', context.route.name) } register the middleware in nuxt.config.js: module.exports = { … router: { middleware: 'pages' } } @sarah_edo

Slide 67

Slide 67

In layouts/default.vue: <template> <div> <app-navigation /> <nuxt/> </div> </template> In AppNavTransition.vue: <h2 key="profile-name" class="profile-name"> <span v-if="page ===$$ 'group'" class="user-trip">{{ selectedUser.trip }}</span> <span v-else>{{ selectedUser.name }}</span> </h2> @sarah_edo

Slide 68

Slide 68

<transition-group /> Flip under the hood Rosario’s article @sarah_edo

Slide 69

Slide 69

Transition Group wraps it... <transition-group name="layout" tag="g"> <rect class="items rect" ref="rect" key="rect" width="171" height="171"/> ... </transition-group> Styles: .items, .list-move { transition: all 0.4s ease; } .active { .rect { transform: translate3d(0, 30px, 0); } ... } @sarah_edo

Slide 70

Slide 70

@sarah_edo

Slide 71

Slide 71

My Demo vue/nuxt page-transitions.com github.com/sdras/page-transitions-travelapp Simona Cotin fork angular/typescript github.com/simonaco/page-transitions-travelapp Shawn wang fork react/next github.com/simonaco/page-transitions-travelapp @sarah_edo

Slide 72

Slide 72

Animate CSS Grid github.com/aholachek/animate-css-grid/ @sarah_edo

Slide 73

Slide 73

Give life to our work

Slide 74

Slide 74

Thank you! @sarah_edo