css3动画transition transform性能对比及原理,用animation实现进度条动效

本文你将看到:

  1. Vue页面初始化加载进度条动画:animation方式
  2. transition ,transform, translate三者的用法(一年之内不写就忘)
  3. 动画性能对比

1. Vue页面初始化加载进度条动画 :animation方式

场景:
今天要写一个进度条动画,但是我平时写简单的动效都是用transition+transform的方式,已经习惯了,但这个动画的场景是页面一载入就执行,transition的方式的话,常用方式总是需要hover或者一些动作才能触发。所以我选择了animation,以为很简单,但实际写起来没想到真的很简单。印象中有动画性能比较这件事,所以我又学了点东西,后续有写到。

效果:
进入页面时播放动画,浮标从头移动,停在指定位置。我不方便录屏。

image.png

思路:

  1. 元素分为两部分:浮标buoy和进度条bar

  2. 页面挂载完成mounted时执行函数,为元素添加动画类。
    此处注意ref是空对象,因此在mounted阶段取值,nextTick方式也可以。

  3. 进度条bar思路相同,只不过如图,灰色底色不动,上层黄色用遮罩方式,执行动画。

  4. animation还有许多属性,可以做复杂的动画,可以自己去学习。

HTML


            

JS

      mounted() {
            // 执行进度条动画
            this.animation();
        },

        methods: {
            animation() {
                if (this.$refs && this.$refs.buoy && this.$refs.bar) {
                    let elBuoy = this.$refs.buoy;
                    let elBar = this.$refs.bar
                    console.log(this.$refs)
                    if (this.grade && this.grade > 0) {
                        switch (true) {
                            case 0 < this.grade && this.grade <= 35 :
                                elBuoy.className = 'buoy buoy-moving-step-1';
                                elBar.className = 'bar-yellow-modal bar-step-1';
                                break;
                            case 35 < this.grade && this.grade <= 65 :
                                elBuoy.className = 'buoy buoy-moving-step-2';
                                elBar.className = 'bar-yellow-modal bar-step-2';
                                break;
                            case 65 < this.grade :
                                elBuoy.className = 'buoy buoy-moving-step-3';
                                elBar.className = 'bar-yellow-modal bar-step-3';
                                break;
                        }
                    }
                }

            }
        }

CSS,只贴了浮标的样式,bar同理。

            .buoy {
                width: 12px;
                height: 12px;
                margin-bottom: 5px;
            }
            .buoy-moving-step-1{
                animation: buoy-moving-step-1 1s ease-out;
                animation-fill-mode: forwards;
            }
            .buoy-moving-step-2{
                animation: buoy-moving-step-2 1.5s ease-out;
                animation-fill-mode: forwards;
            }
            .buoy-moving-step-3{
                animation: buoy-moving-step-3 1.8s ease-out;
                animation-fill-mode: forwards;
            }
    @keyframes buoy-moving-step-1 {
        0% {
            margin-left: 0;
        }
        100% {
            margin-left: 111px;
        }
    }
    @keyframes buoy-moving-step-2 {
        0% {
            margin-left: 0;
        }
        100% {
            margin-left: 222px;
        }
    }
    @keyframes buoy-moving-step-3 {
        0% {
            margin-left: 0;
        }
        100% {
            margin-left: 300px;
        }
    }

2. transition ,transform, translate三者的用法

从英文释义上来理解:
transform:变换,参数可以是translate,scale,rotate等;
translate:位移,是transform的一个属性;
transition:过渡,是唯一有时间参数的!transform可以作为他的一个参数。
例子:

transition:transform 2s ease-in , border-radius 3s ease-out; //可同时设置多个属性的动画,用逗号隔开

transform:translateX(50px);

3. 动画性能对比 transition < transform ,position < translate,animation适合场景

写法举例,我们实现一个动画,鼠标悬浮在元素上,元素的宽度变化。

transition方式:


    

transform 方式:(也是要使用transition的)


    

animation 方式:

.block {
        animation: widen 2s ease;
        animation-fill-mode: forwards;
    }

    @keyframes widen {
        from {
            width: 100px;
        }
        to {
            width: 200px;
        }
    }

铺垫知识

  • 浏览器渲染页面的任务由两个线程完成:主线程 和 排版线程
  • GPU:
    GPU上合成涂层可以在涉及大量像素的绘图和合成操作中实现比CPU还要好的效率,硬件专为这些类型的负载而设计。更详细的知识参考链接:https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/
  • 渲染过程:
    不同属性值引起的重新绘制有3种路径:
    1. layout->paint->composite
    2. paint->composite
    3. composite
      CSS的属性也就此分为3大类:布局类(layout),绘制类(paint),合成类(composite)
      composite 属性目前只有两个:transform和opacity

transition:

transition做动画时两个线程的工作情况是:对于浏览器来说,元素的高度一直在变化,因此这个动画的每一帧都需要主线程对元素进行布局,绘制成位图,将位图交由GPU线程,GPU将位图绘制到屏幕。两个线程来回切换工作,即使是移动十几个像素,主线程也需要对元素布局很多次,这部分的工作消耗相当大,相对较慢,这也是transition动画经常卡顿的原因。


CSS_transition的性能探究.png

transform:

使用transform时浏览器的工作情况是:主线程对元素进行布局,绘制成位图,交由GPU线程,transform执行的整个过程都在GPU进程执行绘制,两个线程来回切换的情况不多,而且transform不会触发浏览器的重新排版,不会影响周围的布局,这也意味着这种情况的动画比transition流畅一些。

CSS_transform的性能探究.png

position VS translate

当页面需要位移动画时,可能会用到这两种,position的原理和transition符合,会触发浏览器的重排,translate不会,所以最好选择transform的translate,rotate,scale等方法。

animation

transition是使一个或多个属性值产生过渡效果,animation则作用于元素本身,强调流程与控制,是关键帧动画的范畴。简单的效果可以用animation,复杂的或想要更自由地掌控应该选择animation。我认为animation会更占资源一些。

硬件加速 will-change + translateZ(0)

transform:translate3d(0,0,0);
transform:translateZ(0);
will-change:transform;

参考:
https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/
https://juejin.im/entry/59dc9aedf265da43200232f9

你可能感兴趣的:(css3动画transition transform性能对比及原理,用animation实现进度条动效)