动画是快速播放的多张照片,人眼对此产生错觉,以为是活动的画面。
浏览器渲染原理
渲染过程
根据 HTML 构建 DOM(Document Object Model)树
根据 CSS 构建 CSSOM(CSS Object Model)树
将二者合并成渲染树(render tree)
layout 布局(文档流、盒模型、计算大小和位置)
paint 绘制(把边框颜色、文字颜色、阴影等画出来)
composite 合成(根据层叠关系展示画面)
如何更新样式
一般用 JS 更新样式,例如:
div.style.background = 'red'
div.style.display = 'none'
div.classList.add('red')
div.remove()
三种更新方式:
查看属性的渲染流程
https://csstriggers.com/
CSS 动画优化
transform - CSS: Cascading Style Sheets | MDN
常用功能:
位移 translate
缩放 scale
旋转 rotate
倾斜 skew
语法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
none | <transform-list>
where
<transform-list> = <transform-function>+
where
<transform-function> = <matrix()> | <translate()> | <translateX()> | <translateY()> | <scale()> | <scaleX()> | <scaleY()> | <rotate()> | <skew()> | <skewX()> | <skewY()> | <matrix3d()> | <translate3d()> | <translateZ()> | <scale3d()> | <scaleZ()> | <rotate3d()> | <rotateX()> | <rotateY()> | <rotateZ()> | <perspective()>
where
<matrix()> = matrix( <number>#{6} )
<translate()> = translate( <length-percentage> , <length-percentage>? )
<translateX()> = translateX( <length-percentage> )
<translateY()> = translateY( <length-percentage> )
<scale()> = scale( <number> , <number>? )
<scaleX()> = scaleX( <number> )
<scaleY()> = scaleY( <number> )
<rotate()> = rotate( [ <angle> | <zero> ] )
<skew()> = skew( [ <angle> | <zero> ] , [ <angle> | <zero> ]? )
<skewX()> = skewX( [ <angle> | <zero> ] )
<skewY()> = skewY( [ <angle> | <zero> ] )
<matrix3d()> = matrix3d( <number>#{16} )
<translate3d()> = translate3d( <length-percentage> , <length-percentage> , <length> )
<translateZ()> = translateZ( <length> )
<scale3d()> = scale3d( <number> , <number> , <number> )
<scaleZ()> = scaleZ( <number> )
<rotate3d()> = rotate3d( <number> , <number> , <number> , [ <angle> | <zero> ] )
<rotateX()> = rotateX( [ <angle> | <zero> ] )
<rotateY()> = rotateY( [ <angle> | <zero> ] )
<rotateZ()> = rotateZ( [ <angle> | <zero> ] )
<perspective()> = perspective( <length> )
where
<length-percentage> = <length> | <percentage>
translate
语法示例:
1
2
3
4
5
transform : translate ( 12px , 50 %); /* X, Y */
transform : translate3d ( 12px , 50 %, 3em ); /* X, Y, Z */
transform : translateX ( 2em );
transform : translateY ( 3in );
transform : translateZ ( 2px );
取值效果:
scale
语法示例:
1
2
3
4
5
transform : scale ( 2 , 0 . 5 );
transform : scale3d ( 2 . 5 , 1 . 2 , 0 . 3 );
transform : scaleX ( 2 );
transform : scaleY ( 0 . 5 );
transform : scaleZ ( 0 . 3 );
取值效果:
scale 使用较少,因为容易模糊。
rotate
语法示例:
1
2
3
4
5
transform : rotate ( 0 . 5turn ); /* 和 rotateZ 一样 */
transform : rotate3d ( 1 , 2 . 0 , 3 . 0 , 10deg );
transform : rotateX ( 10deg );
transform : rotateY ( 10deg );
transform : rotateZ ( 10deg );
取值效果:
rotate 或者 Z > 0,垂直于屏幕顺时针旋转;rotate < 0,逆时针旋转。
X 和 Y 值已经无法用语言解释了,只能想象了。
skew
语法示例:
1
2
3
transform : skew ( 30deg , 20deg );
transform : skewX ( 30deg );
transform : skewY ( 1 . 07rad );
取值效果:
X > 0,向左倾斜;X < 0,向右倾斜。
Y > 0,向上倾斜;Y < 0,向下倾斜。
组合使用
1
2
transform : scale ( 0 . 5 ) translate ( -100 %, -100 %);
transform : none ; /* 取消效果 */
跳动的心
transition | animation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width" >
< title > JS Bin</ title >
</ head >
< body >
< div id = "heart" >
< div class = "left" ></ div >
< div class = "right" ></ div >
< div class = "bottom" ></ div >
</ div >
</ body >
</ html >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
* {
margin : 0 ;
padding : 0 ;
box-sizing : border-box ;
}
# heart {
margin : 100 px ;
position : relative ;
display : inline - block ;
transition : all .5 s ;
}
# heart : hover {
transform : scale ( 1.5 );
}
# heart > . bottom {
width : 50 px ;
height : 50 px ;
transform : rotate ( 45 deg );
background : red ;
}
# heart > . left {
width : 50 px ;
height : 50 px ;
border : 1 px solid red ;
position : absolute ;
bottom : 100 % ;
right : 100 % ;
transform : rotate ( 45 deg ) translateX ( 31 px );
border-radius : 50 % 0 0 50 % ;
background : red ;
}
# heart > . right {
width : 50 px ;
height : 50 px ;
border : 1 px solid red ;
position : absolute ;
bottom : 100 % ;
left : 100 % ;
transform : rotate ( 45 deg ) translateY ( 31 px );
border-radius : 50 % 50 % 0 0 ;
background : red ;
}
transition
transition 用于补充过渡动画。transition 是 transition-property,transition-duration,transition-timing-function 和 transition-delay 的缩写。
语法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* transition 语法 */
transition : 属性名 时长 过渡方式 延迟
/* transition-property 语法*/
transition-property : none ;
transition-property : all ;
transition-property : height ;
/* transition-timing-function 语法 */
transition-timing-function : ease ; /* 和 ease-in-out 类似,但开头比结尾稍快 */
transition-timing-function : ease-in ; /* 先慢后快 */
transition-timing-function : ease-out ; /* 先快后慢 */
transition-timing-function : ease-in-out ; /* 先慢,中间快,后慢 */
transition-timing-function : linear ; /* 匀速 */
transition-timing-function : step-start ;
transition-timing-function : step-end ;
/* transition-duration 语法*/
transition-duration : 6s ;
transition-duration : 120ms ;
transition-duration : 1s , 15s ;
transition-duration : 10s , 30s , 230ms ;
/* transition-duration 语法*/
transition-duration : 6s ;
transition-duration : 120ms ;
transition-duration : 1s , 15s ;
transition-duration : 10s , 30s , 230ms ;
以下情况不能过渡:
display: none -> block
,一般改为 visibility: visible -> hidden
以下情况可以过渡:
background 背景色
opacity 透明度
两段动画怎么做过渡
使用两次 transform
a -> transform -> b -> transform -> c
使用 animation
@keyframes 语法
1
2
3
4
5
6
7
8
9
@ keyframes slidein {
from {
transform : translateX ( 0 % );
}
to {
transform : translateX ( 100 % );
}
}
1
2
3
4
5
6
@ keyframes identifier {
0 % { top : 0 ; left : 0 ; }
30 % { top : 50 px ; }
68 %, 72 % { left : 50 px ; }
100 % { top : 100 px ; left : 100 % ; }
}
animation 语法
示例
animation 属性是 animation-name
,animation-duration
, animation-timing-function
,animation-delay
,animation-iteration-count
,animation-direction
,animation-fill-mode
和 animation-play-state
的缩写。
语法:
animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充方式 | 是否暂停 | 动画名
时长:1s | 1000ms
过渡方式:和 transition 一样,如 linear
次数:2 | 2.4 | infinite
方向:reverse | alternate | alternate-reverse
填充模式:none | forwards | backwards | both
是否暂停:paused | running
参考资料
css - Difference between CSS3 transitions' ease-in and ease-out - Stack Overflow
文章作者
叶寻 | Cyrus Yip
上次更新
2021-11-01
(43e3cd2)