CSS动画原理及应用

2,091 阅读5分钟

动画原理

我们平时看到的动画是由一张一张静态的画面拼接而成的,我们通常用帧数来体现出动画效果的好与坏。 每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。 高的帧率可以得到更流畅、更逼真的动画

帧数就是在1秒钟时间里传输的图片的量,也可以理解为图形处理器每秒钟能够刷新几次,通常用fps(Frames Per Second)表示。

浏览器渲染动画的过程

所有的浏览器渲染动画都要分为以下几步

  1. 根据HTML创建HTML树(DOM)(可以理解成一棵大树,大树的树枝有分叉,每根树枝都会分叉成更小的、更多的树枝;而HTML树也一样,每一个元素都可以形容成一根树枝,每个元素下的子元素都是树枝的分叉)
  2. 根据CSS创建CSS树(CSSOM)(理解方法同上)
  3. 合并两棵树创建RENDER TRee(渲染树)(把两个内容变成一个完全体)
  4. LAYOUT 布局(文档流、盒模型、计算大小和位置以及文字的颜色,好比画家画线稿)
  5. PAINT 绘制<把边框的颜色、文字颜色、以及阴影画出来,就像画家画完线稿后上色>
  6. COMPOSITE 合成根据层叠关系,进行展示画面(把以上流程走完的作品拍扁打包变成一个东西)

浏览器更新样式的步骤和更新方式

一般我们用JS来更新样式,这也是最普遍的更新样式方法,一般分为以下五步,但是根据代码以及浏览器不同,所执行的步骤可能会有删减

  • 执行JS(javascript)-更新样式(style)-布局(layout)-绘制(paint)-合成(composite)

举个例子

  1. div.remove() (直接删掉这个节点,并将全部流程走完后在别处重新创建节点)
  2. div.style.background='red'(改变背景颜色,这样会跳过布局(layout)直接进入绘制(paint)阶段)
  3. div.transform(把这个元素拿起来,移动,再放下。这样只走style、composite两步即可)

如何知晓哪个属性触发什么流程

  • 程序员是爱分享的,已经有大牛将所有属性整理出来了,直接点击参考就好点击跳转

动画优化方式

  • JS优化: 使用repuestAnimationFrame代替setTimeout或者setlnterval
  • css 优化: 使用will-change 或者translate
  • 大牛整理出了全部优化方法,非常详细点击查看

语法属性

transform四个常用功能全解

位移translate

  • translate有三种属性,x、y、z,x代表横向移动,y代表纵向移动,z代表远近移动,例
#demo{
    transform:translatex(50px);
}
  • z属性需要有一个视点(三维的中心点),以视点为中心来移动translate,例
#demo{
    transform:translatez(50px);
}
.wrapper{
    perspective:1000px;
}
  • x、y可以同时使用,之间可以用逗号隔开,x、y、z前面加上3d后也可以这样用
#demo{
    transform:translate3d(50px,50px,50px);
}
  • 分享一个用translate来使元素绝对定位居中的方法
#demo{
    width:100px;
    height:100px;
    position:absolute;
    left:50%;
    top:50%;
    transform:translatex(-50%) translatey(-50%)
}
  • 特别注意:使用此属性的情况下,必须要配合 transition 过渡;行内元素(inline)不支持变形,需要先把它变成块级元素(block)。

缩放scale

  • 用法同位移元素translate相同,同样支持x、y
  • 需要注意的是边框(border)也会随着元素缩放而缩放
  • 这个属性用的比较少,因为会出现模糊的现象

旋转rotate

  • 这个属性同样有x、y、z三个轴,x轴旋转时会沿着横轴方向旋转(看起来就像缩放一样),y轴同x轴一样,z轴是按中心点顺时针旋转
  • 用法同位移元素translate相同
  • 旋转用度数表示,deg表示度数

倾斜skew

  • 用法同位移元素translate相同,同样支持x、y
  • 用起来就好像是把一个矩形倾斜成平行四边形一样,也分x、y轴,也是按度数倾斜

transition属性

transition属性的作用是补充中间帧(你只需要告诉它开始怎么样,结束怎么样,过程动画它会自动补齐)

语法

  • transition:属性名、时长、过渡方式、延迟(通常我们都是用all来代表所有属性)例
#heart{
transition: xxx all 1s;
}

transition属性的过渡方式

  • linear(线性)
  • ease(非线性)
  • 全部方式可以查找相关资料

注意事项

不是所有的属性都可以过渡,切记!!!

例:display:none 变成 block 则无法进行过渡,一般用visibility:hidden 转换成:visible

animation、keyframes的使用方法

keyframes

  • keyframes要声明一个关键帧,然后让动画样式跟着改变,具体用法是@keyframes 名字 {样式}。例
    (图左边为开始与结束两个点,图右边为设置多个关键帧)

animation

animation的用法是声明关键帧后,在元素中声明animation来以何种方式运行动画,例

#heart{
animation:1.5s alternate aaa infinite;
}

可以声明的元素有:时长 过渡方式 延迟 次数 方向 填充模式 是否暂停 动画的名称

  • 时长:s(秒)或ms(毫秒)
  • 过渡方式:跟transition取值一样,如linear
  • 方向:reverse(返向)|alternate(反复进行)|alternate-reverse(返向反复进行)
  • 填充模式:forwards(结束后停留)|backwards(倒退)
  • 是否暂停:paused|running

最后,一颗跳动的心献给大家

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style>
  *{box-sizing: border-box}
#heart>.left{
  background: red;
  width: 50px;
  height: 50px;
  position: absolute;
  transform: rotate(45deg) translateX(31px);
  bottom: 50px;
  left: -50px;
  border-radius: 50% 0 0 50%;
}
#heart>.right{
  background: red;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  position: absolute;
  transform: rotate(45deg) translateY(31px);
  bottom: 50px;
  right: -50px;
  border-radius: 50% 50% 0 0;
}
#heart>.bottom{
  background: red;
  width: 50px;
  height: 50px;
  transform: rotate(45deg);
}
#heart{
  display: inline-block;
  margin: 100px;
  position: relative;
animation:1.5s alternate aaa infinite;
}
@keyframes aaa{
  form{
    transform:scale(1)
  }
  to{
    transform:scale(1.5)
  }
}

  </style>
</head>
<body>
  <div id="heart">
    <div class="left"></div>
    <div class="right"></div>
    <div class="bottom"></div>
  </div>
</body>
</html>