前端三种动画绘制效率对比

  为了MG的开发,考虑了几种动画绘制的方案,开发量虽然不大,但是还是研究对比了一下几种方案的效率性能差异。

  三种:Canvas序列帧动画,Lottie的JSON动画叠加绘制,Vue组件绑定gif动图叠加绘制。

对比主要考虑CPU,GPU,内存上的消耗,下面是测试代码:

复制代码
<!DOCTYPE html>
<html>

<head>
    <title>Canvas tutorial</title>
    <style type="text/css">
        canvas {
            border: 1px solid black;
        }

        * {
            margin: 0
        }
    </style>
</head>

<body>
    <canvas id="tutorial"></canvas>
<!-- 
    采用帧动画,资源消耗更少,胜在可控速度
    内存稳定更少得多
    绘制速率超过原gif大约1.2倍左右时。gpu占用率与img组件齐平
    cpu相对也更低
 -->
</body>
<script type="text/javascript">
    var canvas;
    var ctx;
    var imgs=[];
    function pre() {
        canvas=document.getElementById('tutorial');
        ctx=canvas.getContext('2d');
        canvas.width=window.innerWidth;
        canvas.height=500;

        for (let i=0; i<53; ++i) {
            imgs[i]=new Image();
            // imgs[i].src="./imgs/动作-"+(i+1)+".png";
            imgs[i].src="./new_imgs/动作-"+(i+1)+".png";
        }
        var num=0;
        for (let i=0; i<imgs.length; ++i) {
            imgs[i].onload=function () {
                num++;
                console.log("num==", num);
                if (num==imgs.length) {
                    start();
                }
            }
        }
    };
    pre();
    function start() {
        var i=0;
        var time=2500;
        var fps=imgs.length;
        // 需要一个绘图中心
        var x=imgs[0].width/2;
        var y=imgs[0].height/10*9;
        var len=80;
        ctx.fillStyle="rgb(100,100,0)";
        setInterval(() => {
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            ctx.drawImage(imgs[i], 0, 0);
            ctx.drawImage(imgs[i], 0, 100);
            ctx.drawImage(imgs[i], 0, 200);
            i=(i+1==imgs.length? 0:i+1);
            // console.log("i==", i);
        }, time/fps);
    }
</script>

</html>
Canvas序列帧动画
复制代码
复制代码
<!DOCTYPE html>
<html>

<head>
    <title>Canvas tutorial</title>
    <script type="text/javascript" src="./vue.min.js"></script>
    <script type="text/javascript" src="./vue.js"></script>
    <style type="text/css">
        canvas {
            border: 1px solid black;
            position: relative;
        }

        img {
            position: absolute;
            /* top: 100px;
            left: 100px; */
        }

        * {
            margin: 0
        }
    </style>
</head>

<body>
    <!-- 
        采用img组件,cpu和内存和gpu占用率都更高
     -->
    <canvas id="tutorial"></canvas>
    <div id="my_img">
        <img v-show="flag" :src="src" alt="" :style="style1">
        <img v-show="flag" :src="src" alt="" :style="style2">
        <img v-show="flag" :src="src" alt="" :style="style3">
    </div>
    <button type="button" onclick="change()">切换</button>
</body>
<script type="text/javascript">
    const vm=new Vue({
        el: "#my_img",
        data() {
            return {
                flag: false,
                src: "./new动作.gif",
                style1: {
                    top: 100+'px',
                    left: 100+'px'
                },
                style2: {
                    top: 200+'px',
                    left: 100+'px'
                },
                style3: {
                    top: 300+'px',
                    left: 100+'px'
                }
            }
        }
    })
    function change() {
        Vue.set(vm, "flag", !vm.flag);
        console.log("执行切换", vm.flag);
    }
    var canvas;
    var ctx;
    var imgs=[];
    function pre() {
        canvas=document.getElementById('tutorial');
        ctx=canvas.getContext('2d');
        canvas.width=window.innerWidth;
        canvas.height=500;

        ctx.save();
        ctx.fillStyle="rgb(100,100,0)";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.restore();
    };
    pre();
</script>

</html>
Vue组件绑定GIF动图叠加动画
复制代码

(Vue的jar包和图片资源就不给了,阅者有需要自行替换)

Canvas序列帧动画与Vue组件绑定GIF动图叠加动画对比结果是:

  Canvas序列帧更优:

    内存上,任何情况都远胜于Vue组件绑定方式

    CPU和GPU,在近似的动图绘制速率情况下,Canvas仍然更优。

    大约在1.2倍数左右,GPU消耗齐平

    CPU的齐平倍率大概是1.5。

  另外一点,对于叠加动画而言,不可能是单个动画怼进画面就完事了,还得要调绘制位置和动图大小,甚至是绘制速率同步。

  在这一方面,Canvas序列帧动画绘制都能轻松做到,但是Vue组件绑定不能实现绘制速率的控制(硬要钻牛角尖,也可以去PS单独绘制一份自己制定的速率动图,但是总归是不如Canvas改一改参数就好更方便)

综上:Canvas的序列帧动画完胜,另外还有一个Lottie的Json动画绘制,参考:here

(结论也是序列帧更优,所以,这里就不去对比Vue组件绑定与Lottie的Json动画了)

【Over】

posted @   Renhr  阅读(447)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示