P E N
&
P A P E R
T O
P E N
&
P A P E R
T O
S V G
A N I M A T I O N S S V G
A N I M A T I O N S
lis ilin h ar t . in f o @ lis i_ lin h ar t in s t agr am . co m / lis i. lin e . ar t AN IL LU STR ATIO N A DVEN TU REAN IL LU STR ATIO N A DVEN TU RE
A presentation at pitercss_conf in June 2018 in St Petersburg, Russia by Lisi Linhart
P E N
&
P A P E R
T O
P E N
&
P A P E R
T O
S V G
A N I M A T I O N S S V G
A N I M A T I O N S
lis ilin h ar t . in f o @ lis i_ lin h ar t in s t agr am . co m / lis i. lin e . ar t AN IL LU STR ATIO N A DVEN TU REAN IL LU STR ATIO N A DVEN TU RE
O U R
A D V E N T U R E O U R
A D V E N T U R E D R A W I N G D R A W I N G I S L A N D I S L A N D S V G
R O C K S V G
R O C K A N I M A T I O N A N I M A T I O N C L I F F S C L I F F S
D R A W I N G
I S L A N D D R A W I N G
I S L A N D
I N S P I R A T I O N I N S P I R A T I O N
A N A L Y S I S A N A L Y S I S
S K E T C H I N G S K E T C H I N G
S T R U C T U R E S T R U C T U R E
I N K I N G I N K I N G
C O D I N G C O D I N G
A R T I S T A R T I S T glue toge ther diff er ent ideas to one unison dr awing find simplicit y in their ideas find inspir ation in their surr ounding, mo vies , music cr af t dr awings mas ter simplicit y D E V E L O P E R D E V E L O P E R glue toge ther diff er ent components to one w orking s y s tem find s truc tur e in comple xit y analy se user needs , issues and compe titor s cr af t applications mas ter comple xit y
O N
T O
S V G
R O C K O N
T O
S V G
R O C K
D R A W I N G
S V G
� D R A W I N G
S V G
�
T H E
F I N I S H E D
D R A W I N G T H E
F I N I S H E D
D R A W I N G
T H E
M A G I C
O F T H E
M A G I C
O F A D O B E
I L L U S T R A T O R A D O B E
I L L U S T R A T O R
I M A G E
T R A C E I M A G E
T R A C E
I M A G E
T R A C E
O P T I O N S I M A G E
T R A C E
O P T I O N S
S P L I T
I N T O
L A Y E R S S P L I T
I N T O
L A Y E R S
E X P O R T
A S E X P O R T
A S
E X P O R T
O P T I O N S E X P O R T
O P T I O N S < s v g
" 1 . 1 "
" 0
< g
" f r a m e "
. . . < / g
< g
" a r r o w s "
. . . < / g
< g
6 "
. .
< g
5 "
. .
. . .
< / s v g
O P T I M I S E
W I T H
O P T I M I S E
W I T H
S V G O M G S V G O M G
S V G O
D I F F E R E N C E S V G O
D I F F E R E N C E 2 2 K B
1 2 . 6 K B 2 2 K B
1 2 . 6 K B
S C A L A B L E
S C A L A B L E
V E C T O R
V E C T O R
G R A P H I C S G R A P H I C S
U S E
S V G
F O R U S E
S V G
F O R scalable, r esponsiv e images small file siz es s t yling & animation via C SS debugging in the br o w ser accessibilit y via title at tribute
S V G
A C C E S I B I L I T Y S V G
A C C E S I B I L I T Y use inline S V G does it need alt te xt or is it decor ativ e ? pr o vide a title < s v g
" 0
0
1 0 0
1 0 0 "
" t r u e "
< p a t h
" M 3 . . . . "
< / p a t h
< / s v g
< s v g
" 0
0
1 0 0
1 0 0 "
< t i t l e
A
H i g h
B u i l d i n g < / t i t l e
< p a t h
" M 3 . . . . "
< / p a t h
< / s v g
S V G
A C C E S I B I L I T Y S V G
s v g < s v g
" b u i l d i n g T i t l e "
" 0
0
< t i t l e
" b u i l d i n g T i t l e "
A
B u i l d i n g < / t i t l e
< p a t h
" M 3 . . . . "
< / p a t h
< / s v g
< s v g
" b u i l d i n g T i t l e
b u i l d i n g D e s c "
< t i t l e
" b u i l d i n g T i t l e "
A
B u i l d i n g < / t i t l e
< d e s c
" b u i l d i n g D e s c "
A
d r a w i n g
o f
a
b l a c k
a n d
< p a t h
" M 3 . . . . "
< / p a t h
< / s v g
W H A T
T H E
C O D E
L O O K S
L I K E W H A T
T H E
C O D E
L O O K S
L I K E
< s v g
" h t t p : / / w w w . w 3 . o r g / 2 0 0 0 / s v g "
" 0
0
3 5 2 . 1
3 1 8 "
< g
" f r a m e "
. . . < / g
< g
" a r r o w s "
. . . < / g
< g
6 "
. . . < / g
< g
5 "
. . . < / g
< g
4 "
. . . < / g
< g
3 "
. . . < / g
< g
2 "
. . . < / g
< g
1 "
. . . < / g
< g
" t e x t "
. . . < / g
< g
" s l a s h "
. . . < / g
< / s v g
S V G
V I E W B O X S V G
V I E W B O X
< svg
"0 0 200 100"
... </ svg
svg { width : 200px ;} < svg
"0 0 200 100"
... </ svg
@ media (min-width: 768px ) {
svg { width : 400px ;}
}
S V G
V I E W B O X S V G
V I E W B O X
S V G
&
C S S
=
� S V G
&
C S S
=
�
S V G
&
C S S
T R A N S F O R M S
=
� � S V G
&
C S S
T R A N S F O R M S
=
� �
B R O W S E R
B R O W S E R
I N C O N S I S T E N C I E S ST OP ANIMA TION ST OP ANIMA TION Chrome IE & Opera Firefox Safari (zoomed) E D I T
O N H T M L C S S J S R e s u l t
S V G
&
C S S
T R A N S F O R M S S V G
&
C S S
T R A N S F O R M S In all br o w ser s , p x -based origins ar e measur ed diff er ently f or S V G elements IE and Oper a don't honor C SS tr ansf orms at all on S V G elements Z ooming in Saf ari br eak s the s ync be t w een %- based and p x -based origins css-trick s . com/ s v g-animation- on- css-tr ansf orms/
2
S I M P L E
O P T I O N S 2
S I M P L E
O P T I O N S Use an S V G animation libr ar y lik e GS AP Split into se v er al S V Gs to animate with C SS
S P L I T T I N G
S V G S S P L I T T I N G
S V G S < div
"drawing"
< svg
"drawing__svg"
"0 0 404.7 398.9"
< g
"building-6"
.. </ g
< g
"building-5"
.. </ g
< g
"building-4"
.. </ g
...
</ svg
</ div
const svgEl = document .querySelector( '.drawing__svg' );
const wrapper = svgEl.parentElement;
const svgEl = document .querySelector( '.drawing__svg' );
const wrapper = svgEl.parentElement;
while (svgEl.firstElementChild) {
const newSVG = svgEl.cloneNode();
const childNode = svgEl.firstElementChild;
newSVG.appendChild(childNode);
wrapper.appendChild(newSVG);
}
const svgEl = document .querySelector( '.drawing__svg' );
const wrapper = svgEl.parentElement;
while (svgEl.firstElementChild) {
const newSVG = svgEl.cloneNode();
const childNode = svgEl.firstElementChild;
newSVG.appendChild(childNode);
newSVG.classList.add(
drawing-- ${childNode.getAttribute( 'data-name' )}
);
wrapper.appendChild(newSVG);
}
S P L I T T E D
S V G S P L I T T E D
S V G < d i v
" d r a w i n g "
< s v g
" d r a w i n g _ _ s v g
f r a m e "
" 0
0
4 0 4 . 7
3 9 8 . 9 "
< s v g
" d r a w i n g _ _ s v g
a r r o w s "
" 0
0
4 0 4 . 7
3 9 8 . 9 "
< s v g
" d r a w i n g _ _ s v g
1 "
" 0
0
4 0 4 . 7
3 9
< s v g
" d r a w i n g _ _ s v g
2 "
" 0
0
4 0 4 . 7
3 9
< s v g
" d r a w i n g _ _ s v g
3 "
" 0
0
4 0 4 . 7
3 9
< s v g
" d r a w i n g _ _ s v g
4 "
" 0
0
4 0 4 . 7
3 9
. . .
< / d i v
U S I N G
C S S
V A R I A B L E S
F O R U S I N G
C S S
V A R I A B L E S
F O R A N I M A T I O N A N I M A T I O N
C S S
V A R I A B L E S
I N
C S S C S S
V A R I A B L E S
I N
C S S G L O B A L G L O B A L L O C A L L O C A L U S A G E U S A G E : r o o t
{
p r i m a r y :
t e a l ;
}
b u t t o n
{
p r i m a r y :
d e e p p i n k ;
}
b u t t o n
{
c o l o r :
p r i m a r y ) ;
/ /
d e e p p i n k
}
C S S
V A R I A B L E S
I N
J S C S S
V A R I A B L E S
I N
J S c o n s t
e l e m e n t
=
d o c u m e n t . q u e r y S e l e c t o r ( ' . f o o ' ) ;
e l e m e n t . s t y l e
c o l o r ' ,
' o r a n g e ' ) ;
e l e m e n t . s t y l e
c o l o r ' ) ;
/ /
=
' o r a n g e '
e l e m e n t . s t y l e
c o l o r ' ) ;
W H Y
U S E
V A R I A B L E S
F O R
A N I M A T I O N ? W H Y
U S E
V A R I A B L E S
F O R
A N I M A T I O N ? easily debuggable no e x cessiv e DOM manipulation DOM node independent locally adap table T r ansf orm: Individual P r oper ties
C S S
V A R I A B L E S
S U P P O R T C S S
V A R I A B L E S
S U P P O R T
O F F
T O
A N I M A T I O N
C L I F F S O F F
T O
A N I M A T I O N
C L I F F S
L E T ' S
A N I M A T E L E T ' S
A N I M A T E 1 . Add mousemo v e e v ent
A D D
M O U S E M O V E
E V E N T A D D
M O U S E M O V E
E V E N T c o n s t
{
c l i e n t W i d t h ,
c l i e n t H e i g h t
}
=
d o c u m e n t . d o c u m e n t E l e m e n t ;
d o c u m e n t . a d d E v e n t L i s t e n e r ( ' m o u s e m o v e ' ,
( e )
=
{
/ /
d o
s o m e t h i n g
w i t h
e . c l i e n t X
a n d
e . c l i e n t Y
c o n s t
x
=
e . c l i e n t X ;
c o n s t
y
=
e . c l i e n t Y ;
} ) ;
c o n s t
{
c l i e n t W i d t h ,
c l i e n t H e i g h t
}
=
d o c u m e n t . d o c u m e n t E l e m e n t ;
d o c u m e n t . a d d E v e n t L i s t e n e r ( ' m o u s e m o v e ' ,
( e )
=
{
c o n s t
x
=
e . c l i e n t X
/
c l i e n t W i d t h ;
c o n s t
y
=
e . c l i e n t Y
/
c l i e n t H e i g h t ;
} ) ;
x: 0 x: 1 y: 0 y: 1
c o n s t
{
c l i e n t W i d t h ,
c l i e n t H e i g h t
}
=
d o c u m e n t . d o c u m e n t E l e m e n t ;
d o c u m e n t . a d d E v e n t L i s t e n e r ( ' m o u s e m o v e ' ,
( e )
=
{
c o n s t
x
=
( e . c l i e n t X
/
c l i e n t W i d t h
0 . 5 )
2 ;
c o n s t
y
=
( e . c l i e n t Y
/
c l i e n t H e i g h t
0 . 5 )
2 ;
} ) ;
x: -1 x: 1 y: -1 y: 1
A D D
M O U S E M O V E
E V E N T
A D D
M O U S E M O V E
E V E N T
✔ ✔ c o n s t
{
c l i e n t W i d t h ,
c l i e n t H e i g h t
}
=
d o c u m e n t . d o c u m e n t E l e m e n t ;
c o n s t
w r a p p e r
=
d o c u m e n t . q u e r y S e l e c t o r ( ' . d r a w i n g ' ) ;
d o c u m e n t . a d d E v e n t L i s t e n e r ( ' m o u s e m o v e ' ,
( e )
=
{
c o n s t
x
=
( e . c l i e n t X
/
c l i e n t W i d t h
0 . 5 )
2 ;
c o n s t
y
=
( e . c l i e n t Y
/
c l i e n t H e i g h t
0 . 5 )
2 ;
/ /
s e t
t h e
C S S
V a r i a b l e s
x ' ,
x
) ;
/ /
1
t o
1
y ' ,
y
) ;
/ /
1
t o
1
} ) ;
L E T ' S
A D D
I T
T O G E T H E R L E T ' S
A D D
I T
T O G E T H E R 1 . Add mousemo v e e v ent ✔ 2 . Apply C SS T r ansf orms
A P P L Y
C S S
T R A N S F O R M S A P P L Y
C S S
T R A N S F O R M S S E T
I N
J S S E T
I N
J S S E T
I N
C S S
W I T H
C A L C ( ) S E T
I N
C S S
W I T H
C A L C ( ) wrapper.style.setProperty( '--x' , x ); // -1 to 1
wrapper.style.setProperty( '--y' , y ); // -1 to 1
.drawing--building-1 {
// transform: translate('x-Axis','y-Axis');
transform : translate( 20px , 20px );
}
.drawing--building-1 {
transform : translate (calc(var(--x) * 20px ), calc (var(--y) * 20px ));
}
C S S
T R A N S F O R M S
W I T H
S A S S
M A P S
=
� C S S
T R A N S F O R M S
W I T H
S A S S
M A P S
=
� $svgItems : (building- 1 : 18px , building- 2 : 14px , building- 3 : 10px ,
building- 4 : 8px , building- 5 : 4px , building- 6 : 2px ,
arrow-left: 6px , arrow-right: 6px );
@ each
$key , $value in $svgItems {
.drawing-- #{ $key } {
transform :
translate(calc(var(--x) * #{
$value }), calc(var(--y) * #{ $value }));
}
}
.drawing--building-1 {
transform : translate (calc(var(--x) * 18px ), calc (var(--y) * 18px ));
}
L E T ' S
A D D
I T
T O G E T H E R L E T ' S
A D D
I T
T O G E T H E R 1 . Add mousemo v e e v ent ✔ 2 . Apply C SS T r ansf orms ✔ 3 . Add r eques tAnimationF r ame
A D D
R E Q U E S T A N I M A T I O N F R A M E A D D
R E Q U E S T A N I M A T I O N F R A M E a f u n c t io n
t h at
t h e
b r o w s e r
can
o p t im iz e
it ,
s o
an im at io n s
w ill b e s m o o t h e r an imat io n s
in
in ac t i v e
t ab s
w ill s t o p ,
allo w in g t h e
C PU
t o
ch ill m o r e
b at t e r y -f r ie n d ly n o t
n e ce s s ar y
if
y o u ' r e
u s in g t h e
W e b
A n im at io n s
A p i u s e
can ce lA n imat io n F r am e ( )
t o
can ce l it
A D D
R E Q U E S T A N I M A T I O N F R A M E A D D
R E Q U E S T A N I M A T I O N F R A M E function
repeatOften ( ) {
// Animate something
// call requestAnimationFrame to keep animating
requestAnimationFrame(repeatOften);
}
requestAnimationFrame(repeatOften);
A D D
R E Q U E S T A N I M A T I O N F R A M E
A D D
R E Q U E S T A N I M A T I O N F R A M E
✔ ✔ let x;
document .addEventListener( 'mousemove' , (e) => {
x = (e.clientX / clientWidth - 0.5 ) * 2 ;
// call requestAnimationFrame with update function
requestAnimationFrame(update);
});
function
update ( ) {
// animate changes
wrapper.style.setProperty( '--x' , x );
wrapper.style.setProperty( '--y' , y );
}
L E T ' S
A D D
I T
T O G E T H E R L E T ' S
A D D
I T
T O G E T H E R 1 . Add mousemo v e e v ent ✔ 2 . Apply C SS T r ansf orms ✔ 3 . Add r eques tAnimationF r ame ✔ 4 . Add linear interpolation (lerp )
A D D I N G
L I N E A R
I N T E R P O L A T I O N A D D I N G
L I N E A R
I N T E R P O L A T I O N a w ay to mak e y our animation smoo ther ins tead o f jumping fr om A to B , LERP will go only a fr ac tion o f the w ay on e v er y fr ame combats linear or jagged mo v ement C odepen Ar ticle
A D D I N G
L I N E A R
I N T E R P O L A T I O N A D D I N G
L I N E A R
I N T E R P O L A T I O N function
lerp ( start, end ) {
const dx = end.x - start.x;
const dy = end.y - start.y;
return {
x : start.x + dx * 0.1 ,
y : start.y + dy * 0.1 ,
};
}
W I T H O U T
L E R P W I T H O U T
L E R P W I T H
L E R P W I T H
L E R P
L E T ' S
A D D
I T
T O G E T H E R L E T ' S
A D D
I T
T O G E T H E R 1 . Add mousemo v e e v ent ✔ 2 . Apply C SS T r ansf orms ✔ 3 . Add r eques tAnimationF r ame ✔ 4 . Add linear interpolation ✔ 5 . Add mor e C SS things!
A D D
A D D
M O R E
C S S
T H I N G S ! M O R E
C S S
T H I N G S ! C SS Ho v er Animations C SS S t yling lik e color s Click Lis tener s on Elements R x Obser v ables & Scheduler s to k eep animating once the mouse goes outside the windo w
l i � � . � � n e . � � �
K E E P
H A V I N G
F U N
W I T H
T H E
W E B K E E P
H A V I N G
F U N
W I T H
T H E
W E B A S
A
M E D I U M A S
A
M E D I U M
T H A N K
Y O U ! T H A N K
Y O U !
lis ilin h ar t . in f o @ lis i_ lin h ar t in s t agr am . co m / lis i. lin e . ar t