接着前文看《CSS权威指南》,本文整理一些CSS动画的知识点,同时给出一些例子。css
在CSS动画中咱们常常须要经过变形来达到一些奇妙的效果。使用 transform 首先要明确变形是基于笛卡尔坐标系,也就是一般所说的 x/y/z html
translateX
、translateY
、translateZ
、translate
、translate3d
scaleX
、scaleY
、scaleZ
、scale
、scale3d( number, number, number )
rotateX
、rotateY
、rotateZ
、rotate
、rotate3d( number, number, number, angle)
skewX
、skewY
、skew
perspective( length )
transform-origin
、transform-style
、backface-visibility
在过渡或者动画效果中,咱们可能须要使用贝塞尔曲线 cubic-bezier
来控制动画的步调。咱们能够在这里 设置不一样的曲线并预览,或者在这里 查看一些经常使用的曲线 html5
animation-name
:指定动画的名称animation-duration
:定义动画的时长(ms | s)animation-iteration-count
:声明动画的迭代次数(number | infinite)animation-direction
:设置动画播放的方向(normal | reverse | alternate | alternate-reverse)animation-delay
:延迟播放动画animation-timing-function
:改变更画的内部时序animation-play-state
:设置动画的播放状态(running | paused)animation-fill-mode
:动画的填充模式,也就是动画结束以后的状态(normal | forwards | backwards | both),最终的显示效果与 animation-direction
属性有关animationstart
:动画开始animationiteration
:每次迭代开始animationend
:动画结束给不一样对象赋予必定的延迟时间,每每能够造成一些有趣的动画效果。这里咱们要区分两种延迟:web
animation-delay: <time>
/*假设一个小球来回滚动,每次在两边时停留800ms再继续滚动,咱们能够由如下动画控制*/
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: orange;
animation: move 2000ms infinite alternate;/*alternate 设置来回滚动*/
}
@keyframes move {
0%,
40% {
transform: translateX(0);/*重复关键帧模拟延迟,2000ms × .4 = 800ms*/
}
60%,
100% {
transform: translateX(250px);/*重复关键帧模拟延迟,2000ms × .4 = 800ms*/
}
}
复制代码
live demo若是animation-delay
的值为负,并且绝对值比animation-duration
小,那么动画将当即开始而且从中间的关键帧开始播放。例如,一个动画时长为 10s
,延迟时间为 -4s
,那么若是 animation-timing-function
为 linear
,则将从动画的 40%
开始播放canvas
利用 box-shadow 能够建立为单个元素建立多个 border。例如,咱们能够利用这个属性为一个 loading 动画添加多个小的圆圈。浏览器
// 咱们经过变换box-shadow来交换正方形的位置
.spinner {
position: absolute;
/*border-radius: 50%; need width > 0 and height > 0*/
width: 0;
height: 0;
box-shadow:
-30px -30px 0 40px #a593e0,
-30px 30px 0 40px #e0e3da,
30px 30px 0 40px #fffff3,
30px -30px 0 40px #566270;
animation: spin 3000ms infinite alternate;
}
复制代码
咱们注意到利用 box-shadow 属性,全部“子元素”是绑定在“父元素”上且同时变化的。若是咱们不想引入多余的 DOM 元素,同时又想“子元素”不与“父元素”同时进行变换,咱们能够采用::after
和::before
来建立。
ide
讲完了一些基础知识,让咱们进一步聊聊动画渲染的性能。布局
浏览器的工做原理,请看 How Browsers Work: Behind the scenes of modern web browsers,写的很详尽,值得一读。 性能
现代浏览器一般有两个主要的线程:① main thread;② compositor thread
合成线程会尽量响应用户的鼠标键盘等消息事件。可能发生的状况是,当页面滚动须要更新视图时,合成线程以每帧(60fps)请求更新位图(刷新屏幕),但主线程上可能正进行复杂的脚本运算或者HTML元素绘制,致使合成线程没法及时拿到位图,这时合成线程会绘制空白。
GPU 可以很快地处理将位图绘制到屏幕上的操做,还能很快处理将同一位图经过变换再次绘制的操做,可是对于从内存中加载位图的处理比较慢。比较一个过渡效果使用 height 和 transform 的两个流程:
为何有些动画播放流畅,有些则显得很卡顿呢?从上面的知识中,咱们或许会获得一些启发:现代浏览器在完成 position(位置), scale(比例缩放), rotation(旋转) 和 opacity(透明度)这四种属性的动画时,消耗成本较低。
若是咱们使用 height 进行变换,浏览器可能在每帧须要请求主线程从新布局、绘制和更新位图,再将位图从 CPU 传给 GPU,这个过程可能致使卡顿,也就是咱们丢失了某些关键帧。
可是使用 height 的性能就必定比 transform 的性能差?不必定,可能的状况是:① 绘制的位图很小;② height 更新不会影响其余元素的布局等状况;③ 元素是脱离正常流的;
咱们在使用 width、display、font-size、box-shadow、color 等可能引发重排或者重绘的属性时,若是你不能清楚的知道本身在作什么,咱们仍是建议使用推荐的操做避免糟糕的状况出现。