前端有几种实现动画的方式?

最近把一年前实现过的动画组件整理了一遍,同时也想把相关的这个问题:"前端有几种实现动画的方式?" 的理解分享给大家;

我整理了如下的6种方式,接下来我们以最简单的例子,一个div从左到右移动一定的距离,分别看看这几种方案的具体实现。如有不妥还望指正。

目标效果

开始:

image.png

结果:

image.png

一、CCS animation

这里省略了html部分,我们直接看css:

.box{
    height: 100px;
    width: 100px;
    animation: move 5s linear;
    position: absolute;
    background: #409EFF;
    left: 200px;
}
@keyframes move {
    0%{
        left: 0;
    }
    100%{
        left: 200px;
    }
}
复制代码

二、CSS transition

想到这里我们很容易想到这样去写css来实现一个动画,对的,transition使用的一般场景就是有一个如hover的状态时去改变样式。

.box{
    height: 100px;
    width: 100px;
    left: 0;
    position: absolute;
    background: #409EFF;
    transition: 5s linear;
}
.box:hover{
    left: 200px;
}
复制代码

但是像上面的方式不能实现我们目标需求,所以稍微修改一下:

<style>
    .box{
        height: 100px;
        width: 100px;
        left: 0;
        position: absolute;
        background: #409EFF;
        transition: 5s linear;
    }
    .target{
        left: 200px;
    }
</style>
<script>
    window.onload = ()=>{
        const box = document.getElementsByClassName("box")[0];
        box.className = "target box";
    };
</script>
复制代码

三、setInterval & setTimeout

这里把单纯使用js定时器的方式归为一类,方式如下:

setInterval(move, 10);
const box = document.getElementsByClassName("box")[0];
let n = 0;
function move() {
    if (n>=200) {
        return
    }
    box.style.left = n + 1 + "px";
    n += 1;
}
复制代码
const box = document.getElementsByClassName("box")[0];
let n = 0;
function move() {
    if (n>=200) {
        return
    }
    box.style.left = n + 1 + "px";
    n += 1;
    setTimeout(move,10);
}
move();
复制代码

四、requestAnimationFrame

const box = document.getElementsByClassName("box")[0];
let n = 0;
function move() {
    if (n>=200) {
        return
    }
    box.style.left = n + 1 + "px";
    n += 1;
    requestAnimationFrame(move);
}
move();
复制代码

五、Canvas

因为canvas只能由js操控绘制,其实这种方法也是js的方式实现动画,只是动起来的不是dom元素,而是画布展示;

<body>
    <canvas id="canvas" ></canvas>
</body>
<script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    ctx.clearRect(0,0,300,100);
    ctx.fillStyle = "#409EFF";
    ctx.fillRect(0,0,100,100);
    let n = 0;
    function move() {
        if (n >= 200) {
            return
        }
        ctx.clearRect(0, 0, 300, 100);
        ctx.fillRect(n+1, 0, 100, 100);
        n += 1;
        requestAnimationFrame(move);
    }
    move();
</script>
复制代码

六、SVG

用svg技术来实现,你会发现代码非常少;

<svg>
    <Rect x="200" y="0" width="100" height="100" fill="#409EFF" >
        <animate attributeName="x" from="0" to="200" dur="5"/>
    </Rect>
</svg>
复制代码

总结

上面我们只提出了实现方案,没有对比就没有伤害,那么接着我们来横向对比下各种方式方法的优势和缺点,以及适合使用的场景。

方法 优势 缺点 场景
css animation 可分关键帧定制动画 兼容性 稍复杂动画,
css transition 写法简单 不灵活 元素状态改变时的简单动画
setInterval & setTimeout 兼容性好 卡顿掉帧 不支持css3 的场景
requestAnimationFrame 灵活使用js 兼容性 是定时器的优化方案
Canvas dom少,灵活 js操控编码相对复杂 元素多的复杂动画
SVG 代码少 不支持形变动画 常用于改变位置等自身属性的动画

猜你喜欢

转载自juejin.im/post/7040372629039464484