最近把一年前实现过的动画组件整理了一遍,同时也想把相关的这个问题:"前端有几种实现动画的方式?" 的理解分享给大家;
我整理了如下的6种方式,接下来我们以最简单的例子,一个div从左到右移动一定的距离,分别看看这几种方案的具体实现。如有不妥还望指正。
目标效果
开始:
结果:
一、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 | 代码少 | 不支持形变动画 | 常用于改变位置等自身属性的动画 |