返回

CSS 动画首次循环出现白屏

前端

在使用 CSS 的 animations 属性时,首次加载循环会出现白色的间隙,看着有点像页面有刷新的感觉,后面每次循环就不会再有这个问题。

问题解说

CSS 动画是通过在元素上设置一个关键帧动画来实现的。关键帧动画由一组关键帧组成,每个关键帧指定元素在动画过程中的某个时刻的状态。当动画播放时,浏览器会根据关键帧来计算元素在每个时刻的状态,并将其呈现到屏幕上。

在首次加载动画时,浏览器需要先加载动画的关键帧。在关键帧加载完成之前,浏览器会将元素渲染成初始状态。因此,在关键帧加载完成之前,元素会显示为白色。

问题演示

<!DOCTYPE html>
<html>
<head>
  <style>
    @keyframes example {
      from {
        left: 0px;
      }
      to {
        left: 200px;
      }
    }

    #box {
      width: 50px;
      height: 50px;
      background-color: red;
      animation: example 1s infinite;
    }
  </style>
</head>
<body>
  <div id="box"></div>
</body>
</html>

上面的代码创建一个动画,使一个红色的盒子从左到右移动。首次加载动画时,盒子会先显示为白色,然后才开始移动。

解决办法

有几种方法可以解决这个问题。

1. 使用延迟动画

一种方法是使用延迟动画。延迟动画会在动画开始播放前等待一段时间。这样,浏览器就有足够的时间来加载关键帧,从而避免白屏问题。

<!DOCTYPE html>
<html>
<head>
  <style>
    @keyframes example {
      from {
        left: 0px;
      }
      to {
        left: 200px;
      }
    }

    #box {
      width: 50px;
      height: 50px;
      background-color: red;
      animation: example 1s infinite 1s;
    }
  </style>
</head>
<body>
  <div id="box"></div>
</body>
</html>

上面的代码将动画延迟了 1 秒。这样,浏览器就有足够的时间来加载关键帧,从而避免白屏问题。

2. 使用过渡动画

另一种方法是使用过渡动画。过渡动画是一种简单的动画,它可以在元素之间平滑地过渡。过渡动画不会出现白屏问题,因为浏览器不需要加载关键帧。

<!DOCTYPE html>
<html>
<head>
  <style>
    #box {
      width: 50px;
      height: 50px;
      background-color: red;
      transition: left 1s;
    }

    #box:hover {
      left: 200px;
    }
  </style>
</head>
<body>
  <div id="box"></div>
</body>
</html>

上面的代码创建一个过渡动画,使一个红色的盒子在鼠标悬停时从左到右移动。过渡动画不会出现白屏问题,因为浏览器不需要加载关键帧。

3. 使用 Canvas 元素

还有一种方法是使用 Canvas 元素。Canvas 元素是一个可以用来绘制图形的元素。我们可以使用 Canvas 元素来绘制动画,从而避免白屏问题。

<!DOCTYPE html>
<html>
<head>
  <style>
    canvas {
      width: 50px;
      height: 50px;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>
</html>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var box = {
  x: 0,
  y: 0,
  width: 50,
  height: 50
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.fillStyle = "red";
  ctx.fillRect(box.x, box.y, box.width, box.height);

  box.x += 1;

  if (box.x > canvas.width) {
    box.x = 0;
  }

  requestAnimationFrame(draw);
}

draw();

上面的代码创建一个动画,使一个红色的盒子从左到右移动。Canvas 动画不会出现白屏问题,因为浏览器不需要加载关键帧。

最终效果

使用以上方法,我们可以解决 CSS 动画首次循环出现白屏的问题。