Frontend Engineer @ Upside • Google Code-In Winner • ACS @ UJ
kawka.me • github.com/letelete • linkedin.com/in/brunokawka
Animating the web
Jak nie tracić głowy, kiedy nasze animacje traca klatki?
Bruno Kawka
,
Slide 2
Slide 2 text
Should I even bother with
animations?
Slide 3
Slide 3 text
Performance issues on low-end devices
Motion sickness / Overstimulation / Eye fatigue
Animations equals
Accessibility problem
Should I even bother with animations?
Slide 4
Slide 4 text
Should I even bother with
animations?
motherfuckingwebsite.com
Should I even bother with animations?
Slide 5
Slide 5 text
Should I even bother with
animations?
Enhancing the UX
Imitating the real world
Should I even bother with animations?
Slide 6
Slide 6 text
Enhancing the UX
Should I even bother with animations?
10
3860
Explain core app mechanics
Slide 7
Slide 7 text
Enhancing the UX
Should I even bother with animations?
10
3860
Explain core app mechanics
Slide 8
Slide 8 text
Enhancing the UX
Should I even bother with animations?
9
3860
Explain core app mechanics
Slide 9
Slide 9 text
Enhancing the UX
Should I even bother with animations?
9
3861
Explain core app mechanics
Slide 10
Slide 10 text
Enhancing the UX
Should I even bother with animations?
9
3861
Explain core app mechanics
Slide 11
Slide 11 text
Explain core app mechanics
Should I even bother with animations?
3861
9
Enhancing the UX
Slide 12
Slide 12 text
Guide users over contextful navigation with Hero transitions
Should I even bother with animations?
• Communicate direction of
fl
ow
• Make it clear which elements are related from
page to page.
• Combine them with data fetching for faster
perception of performance.
Enhancing the UX
https://developer.chrome.com/docs/web-platform/view-transitions
Slide 13
Slide 13 text
Explain relationship between elements
Should I even bother with animations?
• Inform about the connection between two
components
Enhancing the UX
https://m3.material.io/styles/motion/transitions/applying-transitions
Slide 14
Slide 14 text
Assure user about the state of the important event with
Should I even bother with animations?
Enhancing the UX
https://tympanus.net/Development/ProgressButtonStyles
Slide 15
Slide 15 text
Describe upcoming changes - Skeletons
Enhancing the UX
Should I even bother with animations?
• Hint at where content will appear once it's loaded
• Hack perception of time - reduce perceived latency
and stabilize layouts as content loads
https://m3.material.io/styles/motion/transitions/transition-patterns
Slide 16
Slide 16 text
Should I even bother with
animations?
Enhancing the UX
Imitating the real world
Should I even bother with animations?
Slide 17
Slide 17 text
Transitions
Should I even bother with animations?
Transitions are fundamental to a great user experience because they
help users understand how an app works. Well-designed transitions
make an experience feel high quality and expressive.
Google Material Design
Slide 18
Slide 18 text
Spring-physics animations
Should I even bother with animations?
https://react-spring-visualizer.com
Slide 19
Slide 19 text
Spring-physics animations
Should I even bother with animations?
https://react-spring-visualizer.com
Slide 20
Slide 20 text
Should I even bother with animations?
The state of Web APIs
Slide 21
Slide 21 text
The state of Web APIs
The state of Web APIs
https://developer.chrome.com/docs/web-platform/view-transitions
Hero transitions API (The View Transitions API)
Slide 22
Slide 22 text
View transition API
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
Slide 23
Slide 23 text
View transition API
The state of Web APIs
const spaNavigate = (data) => {
document.startViewTransition(() => updateTheDOMSomehow(data));
}
Capturing the state
Captures current page (takes a screenshot)
Slide 24
Slide 24 text
View transition API
The state of Web APIs
const spaNavigate = (data) => {
document.startViewTransition(() => updateTheDOMSomehow(data));
}
Captures current page (takes a screenshot)
Add elements / change class names / change styles / …
Modifying the DOM
Slide 25
Slide 25 text
View transition API
The state of Web APIs
::view-transition
└─ ::view-transition-group(root)
└─ ::view-transition-image-pair(root)
├─ ::view-transition-old(root)
└─ ::view-transition-new(root)
Generating pseudo-element tree
Slide 26
Slide 26 text
View transition API
The state of Web APIs
::view-transition
└─ ::view-transition-group(root)
└─ ::view-transition-image-pair(root)
├─ ::view-transition-old(root)
└─ ::view-transition-new(root)
Generating pseudo-element tree
Old captured state, and live representation of the new view
Slide 27
Slide 27 text
View transition API
The state of Web APIs
::view-transition
└─ ::view-transition-group(root)
└─ ::view-transition-image-pair(root)
├─ ::view-transition-old(root)
└─ ::view-transition-new(root)
Customizing the transition with CSS selectors
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 5s;
}
Slide 28
Slide 28 text
View transition API
The state of Web APIs
Identifying elements across the transition
.image {
view-transition-name: hero-image;
}
├
│
│
│
└─ ::view-transition-group(hero-image)
└─ ::view-transition-image-pair(hero-image)
├─ ::view-transition-old(hero-image)
└─ ::view-transition-new(hero-image)
::view-transition
└─ ::view-transition-group(root)
└─ ::view-transition-image-pair(root)
├─ ::view-transition-old(root)
└─ ::view-transition-new(root)
Slide 29
Slide 29 text
View transition API
The state of Web APIs
Hero! Hero! Hero!
.image {
view-transition-name: hero-image;
}
├
│
│
│
└─ ::view-transition-group(hero-image)
└─ ::view-transition-image-pair(hero-image)
├─ ::view-transition-old(hero-image)
└─ ::view-transition-new(hero-image)
::view-transition
└─ ::view-transition-group(root)
└─ ::view-transition-image-pair(root)
├─ ::view-transition-old(root)
└─ ::view-transition-new(root)
View transition API
The state of Web APIs
Resources
https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
https://developer.chrome.com/docs/web-platform/view-transitions
Slide 32
Slide 32 text
Intersection Observer API
The state of Web APIs
Observe changes within an intersection of two elements
• Lazy-load content as page is scrolled / in
fi
nite scrolling
• Deciding whether to perform tasks or animation processes based on the user perception
Slide 33
Slide 33 text
Intersection Observer API
The state of Web APIs
const observer = new IntersectionObserver((entries) => {
Initialize IntersectionObserver
});
Slide 34
Slide 34 text
Intersection Observer API
The state of Web APIs
Viewport
Observed
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
});
const observer = new IntersectionObserver((entries) => {
});
Slide 35
Slide 35 text
Intersection Observer API
The state of Web APIs
Viewport
Observe
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
});
const observer = new IntersectionObserver((entries) => {
});
observer.observe(document.querySelector('.Observed'));
Slide 36
Slide 36 text
Intersection Observer API
The state of Web APIs
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
});
Observed
Viewport
observer.observe(document.querySelector('.Observed'));
});
Slide 37
Slide 37 text
Intersection Observer API
The state of Web APIs
const con
fi
g = {
threshold: 0.75,
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
}, con
fi
g);
observer.observe(document.querySelector('.Observed'));
Viewport
Observed
Slide 38
Slide 38 text
Intersection Observer API
The state of Web APIs
const con
fi
g = {
threshold: 0.75,
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
}, con
fi
g);
observer.observe(document.querySelector('.Observed'));
Observed
Viewport
75%
Slide 39
Slide 39 text
Intersection Observer API
The state of Web APIs
const con
fi
g = {
rootMargin: “-100px”,
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
}, con
fi
g);
observer.observe(document.querySelector('.Observed'));
Viewport
100px
100px
Observed
Slide 40
Slide 40 text
Intersection Observer API
The state of Web APIs
const con
fi
g = {
rootMargin: “-100px”,
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
target.style.backgroundColor = isIntersecting
? 'yellow'
: 'transparent';
});
}, con
fi
g);
observer.observe(document.querySelector('.Observed'));
Observed
Viewport
100px
Slide 41
Slide 41 text
Sometimes, all you need is
the linear interpolation
The state of Web APIs
Slide 42
Slide 42 text
Linear interpolation: Clamp
The state of Web APIs
Given min and max, return the closest value within the bounds
clamp(24, 20, 30) // 24
clamp(12, 20, 30) // 20
clamp(32, 20, 30) // 30
const clamp = (val, min, max) => Math.min(Math.max(val, min), max);
Slide 43
Slide 43 text
Linear interpolation: Lerp
The state of Web APIs
Value between two numbers at a specified, decimal midpoint
lerp(20, 80, 0); // 20
lerp(20, 80, 1); // 80
lerp(20, 80, 0.5); // 50
const lerp = (min, max, val) => min * (1 - val) + max * val;
Slide 44
Slide 44 text
Linear interpolation: Inv. Lerp
The state of Web APIs
Inversed Lerp - Decimal midpoint specified between two
invlerp(50, 100, 75); // 0.5
invlerp(50, 100, 25); // 0
invlerp(50, 100, 125); // 1
const invlerp = (min, max, val) => clamp((val - min) / (max - min), 0, 1);
Slide 45
Slide 45 text
Linear interpolation: Range
The state of Web APIs
Map one data range into another
range(10, 100, 2000, 20000, 50) // 10000
const range = (min1, max1, min2, max2, val) => {
return lerp(min2, max2, invlerp(min1, max1, val));
}
Slide 46
Slide 46 text
Animatable CSS properties
The state of Web APIs
A CSS property is animatable if its value can be made to change over a given
amount of time.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
Slide 47
Slide 47 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
-moz-outline-radius
-moz-outline-radius-bottomleft
-moz-outline-radius-bottomright
-moz-outline-radius-topleft
-moz-outline-radius-topright
-ms-grid-columns
-ms-grid-rows
-webkit-line-clamp
-webkit-text-fill-color
-webkit-text-stroke
-webkit-text-stroke-color
accent-color
all
backdrop-filter
background
background-color
background-position
background-size
Slide 48
Slide 48 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
block-size
border
border-block-end
border-block-end-color
border-block-end-width
border-block-start
border-block-start-color
border-block-start-width
border-bottom
border-bottom-color
border-bottom-left-radius
border-bottom-right-radius
border-bottom-width
border-color
border-end-end-radius
border-end-start-radius
border-image-outset
border-image-slice
Slide 49
Slide 49 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
border-image-width
border-inline-end
border-inline-end-color
border-inline-end-width
border-inline-start
border-inline-start-color
border-inline-start-width
border-left
border-left-color
border-left-width
border-radius
border-right
border-right-color
border-right-width
border-start-end-radius
border-start-start-radius
border-top
border-top-color
Slide 50
Slide 50 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
border-top-left-radius
border-top-right-radius
border-top-width
border-width
bottom
box-shadow
caret
caret-color
caret-shape
clip
clip-path
color
column-count
column-gap
column-rule
column-rule-color
column-rule-width
column-width
Slide 51
Slide 51 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
columns
contain-intrinsic-block-size
contain-intrinsic-height
contain-intrinsic-inline-size
contain-intrinsic-size
contain-intrinsic-width
filter
flex
flex-basis
flex-grow
flex-shrink
font
font-size
font-size-adjust
font-stretch
font-variation-settings
font-weight
gap
Slide 52
Slide 52 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
grid-column-gap
grid-gap
grid-row-gap
grid-template-columns
grid-template-rows
height
inline-size
input-security
inset
inset-block
inset-block-end
inset-block-start
inset-inline
inset-inline-end
inset-inline-start
left
letter-spacing
line-clamp
Slide 53
Slide 53 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
line-height
margin
margin-block
margin-block-end
margin-block-start
margin-bottom
margin-inline
margin-inline-end
margin-inline-start
margin-left
margin-right
margin-top
mask
mask-border
mask-position
mask-size
max-block-size
max-height
Slide 54
Slide 54 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
max-inline-size
max-lines
max-width
min-block-size
min-height
min-inline-size
min-width
object-position
offset
offset-anchor
offset-distance
offset-path
offset-position
offset-rotate
opacity
order
outline
outline-color
Slide 55
Slide 55 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
outline-offset
outline-width
padding
padding-block
padding-block-end
padding-block-start
padding-bottom
padding-inline
padding-inline-end
padding-inline-start
padding-left
padding-right
padding-top
perspective
perspective-origin
right
rotate
row-gap
Slide 56
Slide 56 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
scale
scroll-margin
scroll-margin-block
scroll-margin-block-end
scroll-margin-block-start
scroll-margin-bottom
scroll-margin-inline
scroll-margin-inline-end
scroll-margin-inline-start
scroll-margin-left
scroll-margin-right
scroll-margin-top
scroll-padding
scroll-padding-block
scroll-padding-block-end
scroll-padding-block-start
scroll-padding-bottom
scroll-padding-inline
Slide 57
Slide 57 text
A CSS property is animatable if its value can be made to change over a given
amount of time.
Animatable CSS properties
The state of Web APIs
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
scroll-padding-inline-end
scroll-padding-inline-start
scroll-padding-left
scroll-padding-right
scroll-padding-top
scroll-snap-coordinate
scroll-snap-destination
scroll-timeline
scrollbar-color
shape-image-threshold
shape-margin
shape-outside
tab-size
text-decoration
text-decoration-color
text-decoration-thickness
text-emphasis
text-emphasis-color
Slide 58
Slide 58 text
Animatable CSS properties
The state of Web APIs
text-indent
text-shadow
text-underline-offset
top
transform
transform-origin
translate
vertical-align
visibility
width
word-spacing
z-index
zoom
A CSS property is animatable if its value can be made to change over a given
amount of time.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
Slide 59
Slide 59 text
.class {
transition: ;
will-change: ; ⚠
}
Animatable CSS properties
The state of Web APIs
Just use transition.
Slide 60
Slide 60 text
.class {
transition: ;
will-change: ; ⚠
}
Animatable CSS properties
The state of Web APIs
Just use transition.
Unless… justify-content 😰
Slide 61
Slide 61 text
t
Animatable CSS properties
Unless… justify-content 😰
https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
Just use transition.
Animation discrete
Slide 62
Slide 62 text
Animating layout changes
The state of Web APIs
Problem:
Recalculating layout positions in every frame
60 fps = 60 recalculations per second
60 fps = 16.7 milliseconds to recalculate styles, layout, and paint
(1000ms / 60fps ~= 16.7)
Slide 63
Slide 63 text
The rendering waterfall
Recalculate
Layou
Paint
The state of Web APIs
Slide 64
Slide 64 text
The rendering waterfall
Recalculate
Layou
Paint
Takes DOM Tree, and CSS styles Tree
Creates Render Tree
The state of Web APIs
Slide 65
Slide 65 text
The rendering waterfall
Recalculate
Layou
Paint
Revalidates parts of render tree.
Calculates node dimensions.
A significant cost to performance.
The state of Web APIs
Slide 66
Slide 66 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Pain
Triggers whenever
something
changed its visibility
or appearance.
Slide 67
Slide 67 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Paint
.class {
transition: width ;
}
Slide 68
Slide 68 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Paint
.class {
transition: width ;
}
Slide 69
Slide 69 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Paint
.class {
transition: color ;
}
Slide 70
Slide 70 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Paint
.class {
transition: color ;
}
Slide 71
Slide 71 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Paint
.class {
transition: transform ;
}
Slide 72
Slide 72 text
The rendering waterfall
The state of Web APIs
Recalculate
Layou
Paint
.class {
transition: transform ;
}
Slide 73
Slide 73 text
Cheap animatable properties
The state of Web APIs
transform
opacity
scale
Recalculate Layou Paint
No repaint triggered. Their updates are handled in the composition.
Slide 74
Slide 74 text
Animating layout changes
The state of Web APIs
Problem:
Recalculating layout positions in every frame
60 fps = 60 recalculations per second
60 fps = 16.7 milliseconds to recalculate styles, layout, and paint
Slide 75
Slide 75 text
Animating layout changes
The state of Web APIs
Problem:
Recalculating layout positions in every frame
60 fps = 60 recalculations per second
60 fps = 16.7 milliseconds to recalculate styles, layout, and paint
Solution:
Use properties that are rendered in their own layer
Don’t trigger repaint, and layout recalculation
Slide 76
Slide 76 text
The state of Web APIs
Animating layout changes
Do expensive work cheaply using
the FLIP technique (First Last Invert Play)
Slide 77
Slide 77 text
x: 434
y: 262.5
The state of Web APIs
How FLIP works?
First - the initial state of the element involved in the transition
.container {
display:
fl
ex;
gap: 1rem;
}
Slide 78
Slide 78 text
The state of Web APIs
How FLIP works?
First - the initial state of the element involved in the transition
x1: 216
y1: 0
.container {
display:
fl
ex;
gap: 1rem;
}
Slide 79
Slide 79 text
The state of Web APIs
How FLIP works?
Last - the final state of the element
x1: 216
y1: 0
x2: 0
y2: 216
}
fl
ex-direction: column;
.container {
display:
fl
ex;
gap: 1rem;
Slide 80
Slide 80 text
Inverse - transform element to its initial (First)
position using cheap CSS animatable
properties
The state of Web APIs
How FLIP works?
}
fl
ex-direction: column;
.container {
display:
fl
ex;
gap: 1rem;
transform: translateX
x1: 216
y1: 0
x2: 0
y2: 216
(x1 - x2, y1 - y2)
Slide 81
Slide 81 text
Inverse - transform element to its initial (First)
position using cheap CSS animatable
properties
The state of Web APIs
How FLIP works?
x1: 216
y1: 0
x2: 0
y2: 216
}
fl
ex-direction: column;
.container {
display:
fl
ex;
gap: 1rem;
transform: translateX (216, -216)
Slide 82
Slide 82 text
Play - switch on transitions for changed
properties
and remove the inversion changes
The state of Web APIs
How FLIP works?
}
x1: 216
y1: 0
x2: 0
y2: 216
transition: transform 0.5s ease;
fl
ex-direction: column;
.container {
display:
fl
ex;
gap: 1rem;
transform: translateX (216, -216)
Slide 83
Slide 83 text
Play - switch on transitions for changed
properties
and remove the inversion changes
The state of Web APIs
How FLIP works?
x1: 216
y1: 0
x2: 0
y2: 216
}
transition: transform 0.5s ease;
fl
ex-direction: column;
.container {
display:
fl
ex;
gap: 1rem;
Slide 84
Slide 84 text
Use scale to perform analogical transformations.
Compare First and Last with centered transform origins
The state of Web APIs
FLIP vs geometry
Slide 85
Slide 85 text
Use scale to perform analogical transformations.
Compare First and Last with centered transform origins
The state of Web APIs
FLIP vs geometry
Slide 86
Slide 86 text
Use scale to perform analogical transformations.
Compare First and Last with centered transform origins
The state of Web APIs
FLIP vs geometry
Slide 87
Slide 87 text
When scaling, children will enlarge due to parent transformation.
To avoid it, on every frame, scale children relatively to the parent
The state of Web APIs
FLIP: Beware of child distortions
Child
Child
Slide 88
Slide 88 text
When scaling, children will enlarge due to parent transformation.
To avoid it, on every frame, scale children relatively to the parent
The state of Web APIs
FLIP: Beware of child distortions
Child
Child
Children scales down relatively
to the parent scaling up
childScale = 1 / parentScale
Slide 89
Slide 89 text
When scaling, children will enlarge due to parent transformation.
To avoid it, on every frame, scale children relatively to the parent
The state of Web APIs
FLIP: Beware of child distortions
Child
Child
Children scales down relatively
to the parent scaling up
48pt
48pt
childScale = 1 / parentScale
Slide 90
Slide 90 text
You probably need libraries.
The state of Web APIs
Framer-motion
GSAP
Spring
Lottie
Rive
Three.js
(WebGL)
HeadlessUI
(Tailwind)
Slide 91
Slide 91 text
Framer-motion, GSAP, …
The state of Web APIs
You’ll generally use one of these.
Great for micro-interactions, orchestration, transitions,
timeline-based animations
Slide 92
Slide 92 text
Lottie, Rive
The state of Web APIs
After Effects (or Rive) animations in real time, controlled with code
Slide 93
Slide 93 text
Lottie, Rive
The state of Web APIs
After Effects (or Rive) animations in real time, controlled with code
Slide 94
Slide 94 text
Lottie, Rive
The state of Web APIs
After Effects animations in real time
Slide 95
Slide 95 text
Three.js (WebGL)
The state of Web APIs
Slide 96
Slide 96 text
Three.js (WebGL)
The state of Web APIs
Slide 97
Slide 97 text
Three.js (WebGL)
The state of Web APIs
Slide 98
Slide 98 text
The state of Web APIs
Output
Reference
export const Button = ({ onClick }) => {
return (
{'play'}
);
};
Three.js (WebGL)
The state of Web APIs
Output
Reference
import { useSpring, animated } from ‘@react-spring/web';
export const Button = ({ onClick }) => {
const [isHovering, setIsHovering] = useState(true);
const { transform } = useSpring({
transform: isHovering ? 'scale(1.0)' : 'scale(0.8)',
});
const handleMouseEnter = (e) => {
e.preventDefault();
setIsHovering(true);
};
const handleMouseLeave = (e) => {
e.preventDefault();
setIsHovering(false);
};
return (
{‘play'}
// shadows
);
};
Three.js: The scene (where you arrange objects)
ButtonCanvas
Slide 102
Slide 102 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The scene (where you arrange objects)
Slide 103
Slide 103 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The meshes (objects present in your scene)
Sphere
Slide 104
Slide 104 text
The state of Web APIs
Output
Reference
const states = {
collapsed: {
position: [-0.5, -0.8, -1],
opacity: 0,
},
expanded: {
position: [-1, -1.25, 1],
opacity: 1,
},
};
Three.js: The meshes (objects present in your scene)
Slide 105
Slide 105 text
The state of Web APIs
Output
Reference
const states = {
collapsed: {
position: [-0.5, -0.8, -1],
opacity: 0,
},
expanded: {
position: [-1, -1.25, 1],
opacity: 1,
},
};
Three.js: The meshes (objects present in your scene)
export const Sphere = () => {
const { isHovering } = useContext(ButtonContext);
};
Slide 106
Slide 106 text
The state of Web APIs
Output
Reference
const states = {
collapsed: {
position: [-0.5, -0.8, -1],
opacity: 0,
},
expanded: {
position: [-1, -1.25, 1],
opacity: 1,
},
};
Three.js: The meshes (objects present in your scene)
export const Sphere = () => {
const { isHovering } = useContext(ButtonContext);
};
const { position } = useSpring(
isHovering ? states.expanded : states.collapsed
);
Slide 107
Slide 107 text
The state of Web APIs
Output
Reference
const states = {
collapsed: {
position: [-0.5, -0.8, -1],
opacity: 0,
},
expanded: {
position: [-1, -1.25, 1],
opacity: 1,
},
};
Three.js: The meshes (objects present in your scene)
export const Sphere = () => {
const { isHovering } = useContext(ButtonContext);
};
return (
);
const { position } = useSpring(
isHovering ? states.expanded : states.collapsed
);
Slide 108
Slide 108 text
The state of Web APIs
Output
Reference
const states = {
collapsed: {
position: [-0.5, -0.8, -1],
opacity: 0,
},
expanded: {
position: [-1, -1.25, 1],
opacity: 1,
},
};
export const Sphere = () => {
const { isHovering } = useContext(ButtonContext);
const { position, opacity } = useSpring(
isHovering ? states.expanded : states.collapsed
);
return (
);
};
Three.js: The materials (styles definitions for your meshes)
Slide 109
Slide 109 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 110
Slide 110 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 111
Slide 111 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 112
Slide 112 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 113
Slide 113 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 114
Slide 114 text
The state of Web APIs
Output
Reference
Three.js: The lights (control how your materials act)
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Slide 115
Slide 115 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 116
Slide 116 text
The state of Web APIs
Output
Reference
import { Canvas } from ‘@react-three/
fi
ber';
export const ButtonCanvas = () => (
);
Three.js: The lights (control how your materials act)
Slide 117
Slide 117 text
Should I even bother with animations?
The state of Web APIs
Optimizing the animation
Slide 118
Slide 118 text
Will-change may be a pure evil
Optimizing the animation
.class {
transition: ;
will-change: ; ⚠
}
Slide 119
Slide 119 text
Will-change may be a pure evil
Optimizing the animation
.class {
transition: ;
will-change: ; ⚠
}
Creates composition layer
Slide 120
Slide 120 text
Don’ts: Premature Optimization
Optimizing the animation
“The real problem is that programmers have spent far too much time
worrying about ef
fi
ciency in the wrong places and at the wrong times;
premature optimization is the root of all evil in programming.”
Donald Knuth
Should I even bother with animations?
The state of Web APIs
Optimizing the animation
Accessible animations
Slide 142
Slide 142 text
Let users decide
Accessible animations
All motions enabled? Perfect.
Only gentle motions? No problem.
All motions disabled? Sure.
Give users more control over your product
Slide 143
Slide 143 text
Let users decide
Accessible animations
Give users more control over your product
Slide 144
Slide 144 text
Let users decide
Accessible animations
Give users more control over your product
Slide 145
Slide 145 text
Prefers reduced motion
Accessible animations
@media (prefers-reduced-motion) {
/* styles to apply if the user's settings are set to reduced motion */
}
Has user requested the system to disable non-essential
Slide 146
Slide 146 text
Prefers reduced motion
Accessible animations
@media (prefers-reduced-motion) {
/* styles to apply if the user's settings are set to reduced motion */
}
Has user requested the system to disable non-essential
Slide 147
Slide 147 text
GIF? I want to see the frame.
Accessible animations
Replace GIF with static image on prefers-reduced-motion
Slide 148
Slide 148 text
Accessible animations
Replace GIF with static image on
prefers-reduced-motion
Slide 149
Slide 149 text
Don’ts: Overwriting native
behaviors
Accessible animations
- Keep in mind platform-specific guidelines
- Keep in mind Accessibility (eg. screen readers)
- Don’t overwrite scroll!