返回

手电筒照亮效果:前端实现方法大揭秘!

前端

手电筒效应:用 CSS、Canvas 和 Clipping Path 实现

想象一下,你正穿越一个伸手不见五指的迷宫,手持一把火把照亮前方的路。这束光将周围的空间点亮,但其他地方仍然笼罩在黑暗中。这个场景如何用前端技术来实现呢?

探索 CSS Mask

CSS 中的 mask 属性允许我们裁剪元素的一部分,就像使用遮罩一样。利用它,我们可以创建手电筒的光照范围。在下面的示例中,我们使用一个径向渐变作为遮罩图像,从白色到透明过渡,形成一个圆形的亮区。

.mask {
  width: 200px;
  height: 200px;
  background-color: black;
  mask-image: radial-gradient(circle, white 100%, transparent 0%);
}

模拟光线效果

为了让光线看起来更逼真,我们使用 Canvas 绘制光线路径。在下面的代码中,我们创建一条从指定起点到终点的路径,并使用白色描边和粗细来表示光线。

ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + dx, y + dy);
ctx.strokeStyle = "white";
ctx.lineWidth = 2;
ctx.stroke();

限制光线范围

为了将光线限制在手电筒范围内,我们使用 clip-path 创建一个圆形裁剪路径。这样,光线只能在这个圆形区域内显示。

.container {
  clip-path: circle(100px at center);
}

组合技术,点亮黑暗

通过将这些技术组合在一起,我们可以实现令人印象深刻的手电筒照亮效果。

<div class="container">
  <div class="mask"></div>
  <canvas id="canvas"></canvas>
</div>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

let x = 0;
let y = 0;
let dx = 1;
let dy = 1;

function draw() {
  // 清除画布
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 绘制光线
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x + dx, y + dy);
  ctx.strokeStyle = "white";
  ctx.lineWidth = 2;
  ctx.stroke();

  // 更新光线位置
  x += dx;
  y += dy;

  // 反射光线
  if (x > canvas.width || x < 0) {
    dx = -dx;
  }
  if (y > canvas.height || y < 0) {
    dy = -dy;
  }

  // 循环动画
  requestAnimationFrame(draw);
}

draw();

常见问题解答

  • 如何调整光线范围? 调整 mask 属性中的径向渐变。
  • 如何改变光线颜色? 更改 strokeStyle 属性。
  • 如何让光线动态移动? 使用一个动画循环来更新光线的位置。
  • 如何限制光线的长度? 使用 lineTo() 函数指定光线的终点。
  • 如何优化性能? 使用 requestAnimationFrame() 而不是 setInterval() 来控制动画循环。