Netherspite

transition

  • transition: property duration timing-function delay;
  • transition-property: width; 规定应用过渡的CSS属性的名称
  • transition-duration: 2s; 定义过渡效果花费的时间,默认为0
  • transition-timing-function: linear; 规定过渡效果的时间曲线,默认是ease
  • transition-delay: 2s; 规定过渡效果何时开始,默认为0

animation

需要运用@keyframes规则和animation属性

div{
animation: myfirst 5s;
-moz-animation: myfirst 5s; /* Firefox */
-webkit-animation: myfirst 5s; /* Safari 和 Chrome */
-o-animation: myfirst 5s; /* Opera */
}
@keyframes myfirst{
0% {background: red;}
25% {background: yellow;}
50% {background: blue;}
100% {background: green;}
}
属性名 作用
animation-name 规定 @keyframes 动画的名称
animation-duration 规定动画完成一个周期所花费的秒或毫秒。默认是 0。
animation-timing-function 规定动画的速度曲线。默认是ease。linear
animation-delay 规定动画何时开始。默认是 0。
animation-iteration-count 规定动画被播放的次数。默认是 1。infinite
animation-direction 规定动画是否在下一周期逆向地播放。默认是normal。alternate轮流反向播放
animation-play-state 规定动画是否正在运行或暂停。默认是running。paused
animation-fill-mode 规定对象动画时间之外的状态。forwards保持最后一个属性,backwards应用开始属性

transition和animation也可以结合,以编排不同段用不同的曲线。

@keyframes mykf {
from { top: 0; transition:top ease}
50% { top: 30px;transition:top ease-in }
75% { top: 10px;transition:top ease-out }
to { top: 0; transition:top linear}
}

贝塞尔曲线

timing-function使用的是三次贝塞尔曲线。贝塞尔曲线是一种插值曲线,它描述了两个点之间的差值来形成连续的曲线形状的规则。 一个量从一个值变化到另一个值,插值可以让它平滑地过渡。k次贝塞尔插值算法需要k+1个控制点。一次贝塞尔插值就是线性插值,公式:
$$
B(t)=P_0+(P_1-P_0)t=(1-t)P_0+tP_1, t\in[0,1]
$$
二次贝塞尔插值有三个控制点,公式:
$$
B(t)=(1-t)^2P_0+2t(1-t)P_1+t^2P_2, t\in[0,1]
$$
三次贝塞尔插值是两次二次贝塞尔插值的结果,再做一次贝塞尔插值:
$$
B(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(t-1)P_2+t^3P_3, t\in[0,1]
$$

cubic-bezier是在animation和transition中生产速度曲线的函数,格式为cubic-bezier(<x1>, <y1>, <x2>, <y2>),用法如下:

transition:  all 2s cubic-bezier(.17, .86, .73, .14);

cubic-bezier 的取值范围:

  • P0:默认值 (0, 0)
  • P1:动态取值 (x1, y1)
  • P2:动态取值 (x2, y2)
  • P3:默认值 (1, 1)

常见的cubic-bezier值:

  • ease:cubic-bezier(.25, .1, .25, .1)
  • linear:cubic-bezier(0, 0, 1, 1)/cubic-bezier(1, 1, 0, 0)
  • ease-in:cubic-bezier(.42, 0, 1, 1)
  • ease-out:cubic-bezier(0, 0, .58, 1)
  • ease-in-out:cubic-bezier(.42, 0, .58, 1)

transform

2D方法

  • translate(left, top),位移,根据给定的lefttop位置参数元素从当前位置移动

  • rotate(Xdeg),旋转,元素顺时针(X为负则逆时针)旋转X角度

  • scale(x, y),缩放,元素的尺寸根据给定的宽度和高度增加或减少倍数,负值会使其左右翻转

  • skew(xdeg, ydeg),倾斜,元素根据给定的水平线和垂直线参数翻转给定的角度

  • matrix(a, b, c, d, e, f),将所有2D转换方法组合,参数为六个,对应的矩阵及其变换公式为
    $$
    \left[
    \begin{matrix}
    a & c & e\
    b & d & f \
    0 & 0 & 1
    \end{matrix}
    \right]
    \times
    \left[
    \begin{matrix}
    x\
    y \
    1
    \end{matrix}

    \right]

    \left[
    \begin{matrix}
    ax + cy + e\
    bx + dy + f\
    1
    \end{matrix}
    \right]
    $$
    结果第一行为水平坐标,第二行为垂直坐标

    位移:transform: matrix(1, 0, 0, 1, 100, 100); 向右移动100

    缩放:transform: matrix(s, 0, 0, s, 0, 0); 放大s倍

    旋转:transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0); 旋转θ°

    拉伸:transform: matrix(1,tan(θy),tan(θx),1,0,0)

3D方法

  • translateX(x)/translateY(y)/translateZ(z),元素在X/Y/Z方向上的位移
  • rotateX(angle)/rotateY(angle)/rotateZ(angle),元素围绕X/Y/Z轴以给定的度数旋转
  • scaleX(x)/scaleY(y)/scaleZ(z),元素在X/Y/Z方向上的缩放
  • scale3d(x, y, z),元素的缩放
  • perspective: num,设置元素被查看时元素距视图的距离,以像素为单位
  • perspective-origin: x-axis y-axis,定义元素所基于的X轴与Y轴,改变3D元素的底部位置

requestAnimationFragment

特点

  • 浏览器会确保fn的执行在浏览器一帧的开头
  • 浏览器会自动调节帧率,间接调节了fn的执行频率

不支持raf的浏览器中通常使用setTimeout(fn, 16.7)来实现(16.7ms为每秒60帧的一帧间隔时间)

每一帧执行的过程:JavaScript->Style->Layout->Paint->Composite

JavaScript的执行是在一帧的开头,若浏览器要更新屏幕但当前帧还未完成,那么当前帧就会被丢弃,延迟到下一次更新,即丢帧。尽可能缩短JavaScript执行时间至10ms以内

当有一个大任务的时候,可以分散到每一帧中去执行,比如绘制100个小球,可以每一帧绘制一个,而不是一帧绘制100个

使用requestAnimationFragment注意:

  • 纯计算型、不涉及DOM访问的任务,可以放进Web Workers中
  • 可以使用CSS实现的动画不要用JavaScript实现
  • 对于用户事件的响应,逻辑尽量简单,复杂的逻辑可以延迟处理或分块处理

Style & Layout

使用JavaScript通常的最佳时间是先读取后设置。比如先读取offsetTop再设置top这样不会触发reflow

设置动画时,尽量避免直接改变元素的layout,比如使用transform

Paint

可以将DOM提升到新的composite layer,避免对整个层重新绘制,比如will-change: top;或是使用transform和opacity,这两个被视为合成器属性,在默认情况下会生成新的paint layer

Composite

在Paint阶段可能会发生在多个layer上,最后浏览器通过合并多个layer,根据他们的顺序来正确显示在屏幕上

composite layer提升条件如:

  • 3D相关的CSS样式
  • will-change设置为opacity、transform、top、left、bottom、left
  • fixed(低DPI上不会提升)
  • Hardware-accelerated video element
  • Hardware-accelerated 2D canvas
  • 3D WebGL
  • Overlay(比如A覆盖在B上,而B是提升的composite layer,则A也会被提升到新的layer)

composite layer直接在GPU上完成,渲染速度非常快,但会消耗额外的内存

z-index、absolute等会生成paint layer,每个DOM node都会有对应的layout对象,如果layout对象在同一个坐标系空间,就会在同一个paint layer上。默认情况下,paint layer共享同一个composite layer。


参考文章

  1. 实用的 CSS — 贝塞尔曲线(cubic-bezier)

 评论