You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义光标图片的手电筒效果求助:无法显示黑盒内内容

实现手电筒效果显示黑色盒子内内容

要实现“黑色盒子内的内容仅在手电筒照射区域可见”的效果,核心是利用CSS mask 属性控制内容的显示区域,结合JavaScript跟随鼠标移动调整遮罩位置。以下是修改后的完整实现:

1. HTML结构调整

将盒子内的内容包裹在单独容器中,方便应用遮罩控制:

<!DOCTYPE html>
<html>
<head>
  <title>手电筒效果</title>
  <meta charset="UTF-8" />
</head>
<body>
  <div id="app">
    <div class="box">
      <div class="inner-content">
        <h1>Light</h1>
        <p>这是黑色盒子内的隐藏内容</p>
        <p>只有移动手电筒才能看到</p>
      </div>
    </div>
  </div>
  <script src="src/index.js"></script>
</body>
</html>

2. CSS样式修改

通过mask属性实现内容局部显示,保留自定义光标布局:

body {
  font-family: sans-serif;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
}

.box {
  cursor: none;
  width: 100%;
  max-width: 800px;
  padding: 5rem;
  background-color: #000;
  overflow: hidden;
  position: relative;
}

.inner-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #000;
  background-color: #fff;
  /* 遮罩规则:中心100px半径区域显示内容,其余隐藏 */
  mask-image: radial-gradient(circle, black 0%, black 100px, transparent 100px);
  mask-repeat: no-repeat;
  /* 初始将遮罩移出盒子范围,隐藏全部内容 */
  mask-position: -9999px -9999px;
}

.custom-cursor {
  width: 50px;
  height: 50px;
  position: absolute;
  display: none;
  z-index: 999;
  pointer-events: none;
}

3. JavaScript逻辑优化

移除原可视化用的flashlight元素,直接通过调整内容容器的mask-position实现手电筒跟随:

const box = document.querySelector(".box");
const innerContent = document.querySelector(".inner-content");

const customCursor = document.createElement("img");
customCursor.className = "custom-cursor";
customCursor.src = "https://picsum.photos/50";

box.appendChild(customCursor);

box.addEventListener("mousemove", (e) => {
  const rect = box.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  customCursor.style.display = "block";
  // 让自定义光标居中对齐鼠标位置
  customCursor.style.left = `${x - customCursor.width / 2}px`;
  customCursor.style.top = `${y - customCursor.height / 2}px`;

  // 同步调整遮罩位置,使手电筒中心对准鼠标
  innerContent.style.maskPosition = `${x}px ${y}px`;
});

box.addEventListener("mouseleave", () => {
  customCursor.style.display = "none";
  // 鼠标离开后重置遮罩位置,隐藏内容
  innerContent.style.maskPosition = "-9999px -9999px";
});

实现原理

  • CSS Mask:通过径向渐变创建遮罩,中心100px半径区域为黑色(允许内容显示),其余区域为透明(隐藏内容),完美匹配手电筒的圆形照射范围。
  • 动态跟随:监听鼠标移动事件,实时更新遮罩位置,模拟手电筒随鼠标移动的效果。
  • 光标布局:自定义光标尺寸(50px)小于手电筒半径(100px),满足“手电筒尺寸大于自定义光标”的要求。

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:07:34