CSS动画

403 阅读5分钟

CSS动画

动画的原理

其定义为:有许多静止的画面(帧),以一定的速度(如30张/s)连续播放时,肉眼因视觉残像产生的错觉,而误以为是活动的画面。

帧的概念

帧是指每一个静止的画面,一般影视作品的播放速度为24帧/s,由于游戏对于动画画面质量的要求,最易游戏最低为30帧/s。

我们举一个简单的描述CSS动画的例子:将一个div从左到右移动。 原理:每过一段时间(使用setInterval)将div移动一段距离,直到目标点。

第一种方法:demo相对定位,使用left移动,使用setInterval函数。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Document</title>
    <style>
        #demo{
            width: 100px;
            height: 100px;
            border: 1px solid red;
            position: relative;
            left: 0;
        }
    </style>
</head>
<body>
    <div id="demo"></div>
    <script>
        var n = 1

            var id = setInterval(() => {
                if (n <= 200) {
                    demo.style.left = n + 'px'
                    n = n + 1
                } else {
                    clearInterval(id)
                }
            }, 1000 / 60)
    </script>
</body>
</html>

1.jpg

注意:通过开发者工具之中绘制渲染模块发现在div在移动过程中,一直在渲染,性能不好。如何在使用开发者工具查看渲染情况? 答:先打开开发者工具——在任意选项上按esc,出现一个控制台,点击控制台中左上角的“┇”,选择点击“Rendering”,勾选第一个“Paint flashing”,即可展示渲染情况-显示绿色。

补充

浏览器的渲染原理:

步骤:————三棵树

  1. 根据HTML构建HTML树(DOM)
  2. 根据CSS构建CSS树(CSSOM)
  3. 将两棵树合并成一颗渲染树(render tree)
  4. layout布局(文档流、盒模型、计算大小和位置)
  5. Paint绘制(边框的颜色、文字颜色、阴影等画出来)
  6. Compose 合成(根据层叠关系展示画面)

浏览器渲染原理.png

如何更新样式呢? 答:一般我们都是使用JS来更新样式

例如:

div.style.backgroung = 'red'; 将背景改为红色

div.style.display = 'none'; 改为隐藏

div.classList.add = ('red') 添加一个'red'类。一般高手都是只添加类,不加样式。

div.remove() 直接删除节点

三种更新方式的不同

  1. JS/CSS > 样式 > 布局 > 绘制 > 合成 例子:div.remove()会触发当前消失,其他元素relayout。

  2. JS/CSS > 样式 > 绘制 > 合成 例子:改变背景的颜色。直接repaint+recompose

  3. JS/CSS > 样式 > 合成 例子:改变transform,只需要composite就行。注意必须要在全屏状态看效果,在iframe里面看有bug。

可以在csstriggers.com 里面查看所有属性是什么流程。

CSS动画优化

在这边我们只简单举几个可行的方法。具体的优化内容,我之后会单独出一个文章谈谈。

  1. JS优化:使用requestAnimationFrame代替setTimeout或setInterval.
  2. CSS优化:使用will-change或translate。 我们回到之前做的将一个div从左到右移动,一般高手都不用left,还是使用transform:tranlate来移动div,从性能上来说,translate的渲染没有relayout和repaint,只有开始的样式和最后的合成,比left性能好很多。

CSS动画中常用的属性

tranform

transform有四个常用的功能:

  1. translate——位移
  2. scale——缩放
  3. rotate——旋转
  4. skew——倾斜

translate有以下几种写法:

  • translateX()——正右负左
  • translateY()——正上负下
  • translateZ()——正近负远
  • translate(x,y)
  • translate3d(x,y,z) 注意事项:
  1. 学会看懂MDN文档的语法格式
  2. 绝对居中的写法:
.wrapper{
position:relative;
height:100px;
}
.x{
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
}

scale

scale有下面写法:

  1. scaleX()——按照X轴缩放
  2. scaleY()——按照Y轴缩放 scale用的比较少,因为会导致图像变得模糊。

rotate

rotate的写法:

  1. rotateX()——绕着X轴旋转
  2. rotateY()——绕着Y轴旋转
  3. rotateZ()——绕着Z轴旋转
  4. rotate()

skew

使用方法:

  1. skewX()——绕着X轴旋转
  2. skewY()——绕着Y轴旋转
  3. skew()

以上rotate和skew都是需要用到时再去查MDN文档即可。 多重效果可以使用组合来实现:transform:scale(0.5) translate(100%,100%);

transform:none表示取消所有

transition

过渡

作用:补充中间帧

语法: transition:属性名 时长 过渡方式 延迟

  1. 可以使用,分隔开不同的属性:transition:left 20ms,top 400ms;
  2. 可以使用all代表所有的属性。
  3. 过渡方式有很多种:
  • linear——线性
  • ease——先快后慢
  • ease-in
  • ease-out
  • ease-in-out
  • cubic-bezier
  • step-start
  • step-end
  • steps

注意事项:

  1. 不是所有的属性都可以过渡的。例如:display:none=>display:block就不能过渡。我们一般会改为visibility:hidden=>visibility:visible
  2. 过渡必须要有起始,一次或者两个动画。
  3. 如果动画有个中间的点,需要动两次,如何实现?
  • 使用两次tranform,先有a使用一次transform到b,再从b使用一次transform到c.
  • 使用animation。

animation

语法:

  1. 声明关键帧
  2. 添加动画 例如:
  3. form to
@keyframes slidein{
        form{
    transform:translate(0%);
        }
        to{
    transform:translate(100%)
        }
   }
  1. 百分数
@keyframes identifier{
        0%{top:0;left:0;}
        30%{top:50px;}
        68%,72%{left:50px;}
        100%{top:100px;left:100%;}
    }

补充:如何让动画停在最后一帧:在animation中加一个forwards。

animation:时长|过渡方式|延迟|次数|方向|填充模式|是否暂停|动画名

  1. 时长:1s或1000ms
  2. 过渡方式:跟transition取值一样,如linear
  3. 次数:3或4或infinite(无限)
  4. 方向:reverse(从尾到头) | alternate(回返)| alternate-reverse(从尾到头再回返)
  5. 填充模式:none | forwards(前进) | backwards | both
  6. 是否暂停:paused(暂停) | running(运行) 以上所有属性都有对应的单独属性,可以在MDN文档中查到。