自定义光标图片的手电筒效果求助:无法显示黑盒内内容
实现手电筒效果显示黑色盒子内内容
要实现“黑色盒子内的内容仅在手电筒照射区域可见”的效果,核心是利用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
相关产品推荐
相关产品推荐

