前端实现动画的几种方式

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,用于在浏览器的下一次重绘之前调用指定的函数来更新动画。它使用浏览器自己的优化机制来安排动画,因此通常比使用setTimeoutsetInterval更高效。

<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>
表情
Ctrl + Enter