如何实现鼠标悬停图片时仅显示光标覆盖区域的效果
提问内容
提前说明
您可查看当前本地代码或未实现悬停图片效果的本地演示。
需求说明
我需要实现的效果为:当使用自定义的黑色圆形光标悬停在图片上时,仅显示图片中被光标覆盖的部分,而非完整展示整张图片。
遇到的问题
目前不清楚该从何处入手实现该效果,我曾参考过几个使用Z-Index实现的案例,但一直未能复现成功。若有实现了同类效果的实现方案也可以满足我的需求。
为便于理解需求,我准备了两张示例图:
第一张图中,黑青配色的小型圆形光标悬停在环形文本上,尚未与图片区域重合,因此图片处于隐藏状态。

第二张图中,光标已经悬停在图片的部分区域上,对应区域的图片内容已正常显示。
实现方案
这个效果本质是鼠标跟随的图片局部揭示效果,不需要依赖复杂的z-index层级堆叠实现,用CSS mask 属性配合少量JS即可实现,逻辑更清晰也更容易调试:
- 用径向渐变作为图片的遮罩,遮罩的可见区域大小和自定义光标大小保持一致
- 监听鼠标移动事件,同步更新遮罩的位置和自定义光标的位置即可
完整可运行代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>图片局部揭示效果</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; /* 隐藏系统默认光标 */ cursor: none; } body { min-height: 100vh; background-color: #000; color: #fff; padding: 2rem; } /* 自定义圆形光标 */ .custom-cursor { position: fixed; width: 40px; height: 40px; border: 2px solid #0ff; border-radius: 50%; background-color: rgba(0,0,0,0.8); pointer-events: none; z-index: 9999; transform: translate(-50%, -50%); transition: transform 0.05s ease; } /* 图片容器 */ .img-container { width: 600px; height: 400px; margin: 5rem auto; position: relative; } /* 待揭示的图片 */ .reveal-img { width: 100%; height: 100%; object-fit: cover; /* 径向渐变遮罩:中心40px范围不透明,其余完全透明 */ mask: radial-gradient(circle 20px at 0 0, #000 100%, transparent 100%); /* 兼容webkit内核浏览器 */ -webkit-mask: radial-gradient(circle 20px at 0 0, #000 100%, transparent 100%); /* 遮罩位置默认在可视区域外,默认图片完全隐藏 */ mask-position: -100px -100px; -webkit-mask-position: -100px -100px; mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; } </style> </head> <body> <div class="custom-cursor"></div> <!-- 示例环形文本,可替换为你自己的页面内容 --> <h1 style="text-align: center; font-size: 3rem; margin-bottom: 2rem;">环形文本示例内容</h1> <div class="img-container"> <!-- 替换为你自己的本地图片地址 --> <img src="./test.jpg" alt="待揭示图片" class="reveal-img"> </div> <script> const cursor = document.querySelector('.custom-cursor'); const revealImg = document.querySelector('.reveal-img'); const imgContainer = document.querySelector('.img-container'); document.addEventListener('mousemove', (e) => { // 更新自定义光标位置 cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; // 计算鼠标相对于图片容器的位置 const rect = imgContainer.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // 更新图片遮罩位置 revealImg.style.maskPosition = `${x}px ${y}px`; revealImg.style.webkitMaskPosition = `${x}px ${y}px`; }) </script> </body> </html>
参数调整说明
- 如果你需要调整光标大小,只需要同步修改
.custom-cursor的宽高、以及radial-gradient里的圆半径即可 - 如果需要多个图片都支持这个效果,只需要遍历所有图片容器,分别计算相对位置更新对应图片的遮罩位置即可
- 目前主流浏览器都支持mask属性,兼容性覆盖95%以上的全球用户,不需要额外做降级处理
内容的提问来源于stack exchange,提问作者JueK3y
相关产品推荐
相关产品推荐

