前端实现动画的几种方式
2024-05-31 16:03:53
一. CSS实现
1. transition
transition通常在CSS中被用来描述一个元素从一个状态到另一个状态时的过渡效果。
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
/*
设置了两个过渡效果:
1. 宽度在1秒内平滑过渡(ease-out)
2. 背景色在2秒内平滑过渡(ease-in-out)
*/
transition: width 1s ease-out, background-color 2s ease-in-out;
cursor: pointer;
}
.box:hover {
width: 200px;
background-color: blue;
}
</style>
<div class="box">鼠标悬停我</div>
除了上面的基于hover状态的transition示例,还可以使用JavaScript来动态地改变元素的样式,从而触发transition效果。
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
transition: width 2s ease-in-out; /* 当宽度变化时,应用2秒的ease-in-out过渡效果 */
cursor: pointer;
}
</style>
<div id="box" class="box">见证奇迹</div>
<button onclick="onClick()">点我</button>
<script>
function onClick() {
document.getElementById('box').style.width = '200px';
}
</script>
2. transform
CSS的transform属性允许你对元素进行2D或3D转换。这些转换包括旋转、缩放、倾斜和移动等。
旋转(rotate())
.rotate {
transform: rotate(45deg); /* 顺时针旋转45度 */
}
缩放(scale())
.scale {
transform: scale(1.5); /* 元素放大1.5倍 */
}
倾斜(skew())
.skew {
transform: skew(20deg, 10deg); /* x轴倾斜20度,y轴倾斜10度 */
}
移动(translate())
.translate {
transform: translate(50px, 100px); /* 向右移动50px,向下移动100px */
}
复合转换
.composite {
transform: rotate(45deg) scale(1.5) translate(50px, 100px);
/* 先旋转45度,然后放大1.5倍,最后向右移动50px,向下移动100px */
}
3D转换
CSS还提供了rotateX()
, rotateY()
, rotateZ()
, scaleX()
, scaleY()
, scaleZ()
, translateX()
, translateY()
, translateZ()
等函数用于3D转换。
3. animation
用于创建更复杂的动画,使用@keyframes规则,可以定义多个关键帧和动画的各个阶段。
<style>
@keyframes color {
0% { background-color: red; }
50% { background-color: green; }
100% { background-color: blue; }
}
.box {
width: 100px;
height: 100px;
animation: color 3s linear infinite;
}
</style>
<div class="box"></div>
二. JS实现
1. requestAnimationFrame
这是现代浏览器提供的一个高性能的API,用于在浏览器的下一次重绘之前调用指定的函数来更新动画。它使用浏览器自己的优化机制来安排动画,因此通常比使用setTimeout
或setInterval
更高效。
<style>
.box {
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
background-color: red;
}
</style>
<div id="box" class="box"></div>
<script>
const box = document.getElementById('box');
let start = null;
let x = 0;
let velocity = 2; // 方块移动的速度
function animate(timestamp) {
if (!start) start = timestamp;
const elapsed = timestamp - start;
// 基于时间更新x坐标,使动画更加平滑
x = Math.min(window.innerWidth - 50, elapsed * velocity); // 确保方块不会移出视口
box.style.transform = `translateX(${x}px)`;
// 请求下一帧动画
requestAnimationFrame(animate);
}
// 开始动画
requestAnimationFrame(animate);
</script>