如何实现鼠标移动时的div手电筒透视效果?
手电筒效果实现问题
我想要实现一种手电筒效果:有一个设置为fixed、带渐变背景、宽高100%的div覆盖整个屏幕,希望在鼠标移动时,以手电筒的形式显示该div背后的内容。
我目前无法实现让这个div的局部区域变为透明(opacity: 0),参考效果如下:
当鼠标移动时,“Pré-inscription”按钮会透过遮罩显示,渐变层仅保留在鼠标光标周围(截图中的圆圈太小,后续会调大)。
补充说明:为便于理解,我制作了一个示例,其中有固定的渐变遮罩层,红色圆圈区域本应能透过渐变层看到背后内容。
示例代码
HTML
<h1 class="text-7xl">Coming soon</h1> <div id="overlay"> <div id="magnifier"></div> </div>
CSS
#overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; background: rgb(255,215,108); background: radial-gradient(circle, rgba(251, 92, 3, 1) 0%, rgba(255,215,108,1) 100%); } #magnifier { position: absolute; background: red; width: 7rem; height: 7rem; border-radius: 100%; top: -20rem; left: -20rem; }
JavaScript
let magnifier = document.getElementById('magnifier') let size = magnifier.offsetWidth window.addEventListener('mousemove', (e) => { magnifier.style.top = e.clientY - (size / 2)+'px' magnifier.style.left = e.clientX - (size / 2)+'px' })
请问有解决思路吗?谢谢!
解决思路
你当前的实现思路没法达成局部透明效果,因为子元素无法穿透父元素的渐变背景。可以改用CSS的mask属性来实现遮罩镂空,具体方案如下:
修改后的完整代码
HTML
<h1 class="text-7xl">Coming soon</h1> <div id="overlay"></div>
CSS
#overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgb(255,215,108); background: radial-gradient(circle, rgba(251, 92, 3, 1) 0%, rgba(255,215,108,1) 100%); /* 蒙版设置:中心透明区域为手电筒范围,其余区域显示遮罩渐变 */ mask: radial-gradient(circle, transparent 45%, black 46%); mask-size: 7rem 7rem; mask-repeat: no-repeat; }
JavaScript
const overlay = document.getElementById('overlay') const maskSize = 7 // 单位rem window.addEventListener('mousemove', (e) => { // 计算蒙版位置,让镂空中心跟随鼠标 const posX = e.clientX - (maskSize * 16 / 2) // rem转px,1rem=16px可根据实际调整 const posY = e.clientY - (maskSize * 16 / 2) overlay.style.maskPosition = `${posX}px ${posY}px` })
关键说明
- 核心原理:通过
mask属性给遮罩层添加径向渐变蒙版,透明区域会穿透显示下方内容,黑色区域保留遮罩的渐变背景,完美模拟手电筒效果。 - 调整尺寸:修改
mask-size的值即可改变手电筒的大小,同时调整radial-gradient里的百分比可以优化边缘过渡效果。 - 简化结构:不需要额外的子元素,直接通过控制遮罩层的
mask-position实现跟随鼠标移动。
内容的提问来源于stack exchange,提问作者Axel
相关产品推荐
相关产品推荐

