CSS动画小知识

接着前文看《CSS权威指南》,本文整理一些CSS动画的知识点,同时给出一些例子。css

预备知识

变形 Transform

在CSS动画中咱们常常须要经过变形来达到一些奇妙的效果。使用 transform 首先要明确变形是基于笛卡尔坐标系,也就是一般所说的 x/y/z html

坐标系

  • transform 是基于物体自身的坐标系,百分比也是基于自身的大小
  • 移动和旋转的先后顺序很重要,由于物体旋转以后的坐标系也跟着旋转
  • 经常使用函数(live demo):
    • 平移函数:translateXtranslateYtranslateZtranslatetranslate3d
    • 缩放函数:scaleXscaleYscaleZscalescale3d( number, number, number )
    • 旋转函数:rotateXrotateYrotateZrotaterotate3d( number, number, number, angle)
    • 倾斜函数:skewXskewYskew
    • 视域:perspective( length )
  • 重要属性:transform-origintransform-stylebackface-visibility
See the Pen FlipCard on CodePen.

贝塞尔曲线

在过渡或者动画效果中,咱们可能须要使用贝塞尔曲线 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 属性有关
    live demo

JS动画事件

  • animationstart:动画开始
  • animationiteration:每次迭代开始
  • animationend:动画结束

动画延迟效果

给不一样对象赋予必定的延迟时间,每每能够造成一些有趣的动画效果。这里咱们要区分两种延迟:web

  • 浏览器把动画附加到元素上以后等待多久开始第一次迭代:animation-delay: <time>
  • 每次迭代开始前须要等待:重复关键帧
    animation delay
    /*假设一个小球来回滚动,每次在两边时停留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-functionlinear,则将从动画的 40% 开始播放canvas

利用 box-shadow

利用 box-shadow 能够建立为单个元素建立多个 border。例如,咱们能够利用这个属性为一个 loading 动画添加多个小的圆圈。浏览器

  • 语法:box-shadow: h-shadow v-shadow blur spread color inset;
  • 例子
// 咱们经过变换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

  • 主线程的主要职责是(维持一个RenderLayers):
    • 运行脚本
    • 计算 HTML 元素的 CSS 属性
    • 页面布局
    • 把 DOM 元素绘制到一个或者多个位图上
    • 把合成的位图交给compositor thread
  • 合成线程的主要职责是(维持一个 GraphicsLayers):
    • 经过 GPU 把位图绘制到屏幕上
    • 请求主线程更新呈如今屏幕上或者即将呈如今屏幕上的位图
    • 当进行滚动操做时,弄清楚哪部分即将呈如今屏幕上
    • 当进行滚动的时候,移动相应部分的页面

合成线程会尽量响应用户的鼠标键盘等消息事件。可能发生的状况是,当页面滚动须要更新视图时,合成线程以每帧(60fps)请求更新位图(刷新屏幕),但主线程上可能正进行复杂的脚本运算或者HTML元素绘制,致使合成线程没法及时拿到位图,这时合成线程会绘制空白。

GPU

GPU 可以很快地处理将位图绘制到屏幕上的操做,还能很快处理将同一位图经过变换再次绘制的操做,可是对于从内存中加载位图的处理比较慢。比较一个过渡效果使用 height 和 transform 的两个流程:

composited layer 建立的条件

  • 使用视频加速解码的 video 元素
  • flash、使用3D (WebGL) context 的 canvas 元素
  • CSS transform
  • CSS filter
  • CSS opacity

高性能的 CSS动画

减小消耗成本

为何有些动画播放流畅,有些则显得很卡顿呢?从上面的知识中,咱们或许会获得一些启发:现代浏览器在完成 position(位置), scale(比例缩放), rotation(旋转) 和 opacity(透明度)这四种属性的动画时,消耗成本较低。

若是咱们使用 height 进行变换,浏览器可能在每帧须要请求主线程从新布局、绘制和更新位图,再将位图从 CPU 传给 GPU,这个过程可能致使卡顿,也就是咱们丢失了某些关键帧。

可是使用 height 的性能就必定比 transform 的性能差?不必定,可能的状况是:① 绘制的位图很小;② height 更新不会影响其余元素的布局等状况;③ 元素是脱离正常流的;

咱们在使用 width、display、font-size、box-shadow、color 等可能引发重排或者重绘的属性时,若是你不能清楚的知道本身在作什么,咱们仍是建议使用推荐的操做避免糟糕的状况出现。

JS动画和CSS动画的优缺点

  • 优势:JavaScript中的动画能够为你提供更多的控制,好比开始,暂停,回放,中断和取消等,还能够进行设计复杂的动画效果。缺点:主线程上可能进行复杂的运算,增大掉帧的风险(咱们也能够放在 Web Worker 中进行)。
  • 优势:浏览器会对CSS动画进行优化,若是有须要,它会建立图层,而且能够在主进程以外完成一些操做。缺点就是CSS动画相对于Javascript动画而言,缺少表现力,对动画的设计来讲更加复杂。

参考博客及推荐阅读

相关文章
相关标签/搜索