寻求鼠标跟随的模糊边缘图片局部显示效果优化方案
实现鼠标跟随的模糊渐变边缘局部图片显示效果
嘿,我完全懂你想要的那种交互效果——鼠标移动时,透过一个边缘带自然模糊渐变的圆形窗口,显示另一张图片的局部。之前用box-shadow确实很难做出顺滑的过渡效果,因为阴影的模糊范围和透明度很难精准匹配需求。这里有几个更实用的实现思路,亲测效果更自然:
方案一:CSS Mask(径向渐变遮罩)—— 最简洁的实现
CSS的mask属性可以直接控制元素的显示区域,用径向渐变就能轻松做出中心清晰、边缘模糊渐变的效果,这是目前最推荐的方案,代码改动也最小。
修改后的完整代码
<div class="background"> <div class="reveal"></div> </div>
html, body { font-size: 62.5%; height: 100%; overflow: hidden; margin: 0; } .background { position: relative; height: 100%; background: #000; background: url("http://www.wallpapers4u.org/wp-content/uploads/paper_patterns_backgrounds_textures_lines_36212_1920x1080.jpg") 50% 50% no-repeat fixed; background-size: cover; } .reveal { z-index: 5; position: absolute; width: 20rem; height: 20rem; /* 核心:用径向渐变作为遮罩,实现边缘模糊 */ -webkit-mask: radial-gradient(circle, rgba(0,0,0,1) 60%, rgba(0,0,0,0) 100%); mask: radial-gradient(circle, rgba(0,0,0,1) 60%, rgba(0,0,0,0) 100%); /* 要显示的目标图片 */ background: url("http://gallery.hd.org/_exhibits/textures/text-sample-of-old-novel-DHD.jpg") 50% 50% no-repeat fixed; background-size: cover; }
document.addEventListener('DOMContentLoaded', function() { const reveal = document.querySelector('.reveal'); const revealWHalf = reveal.offsetWidth / 2; const revealHHalf = reveal.offsetHeight / 2; document.addEventListener('mousemove', function(e) { // 让圆形窗口中心跟随鼠标 reveal.style.left = `${e.pageX - revealWHalf}px`; reveal.style.top = `${e.pageY - revealHHalf}px`; }); });
原理说明
mask: radial-gradient(...)定义了一个圆形遮罩:中心60%的区域是完全不透明(显示图片),从60%到100%的范围逐渐过渡到透明,自然形成模糊边缘。- 你可以调整渐变的百分比(比如把
60%改成70%,100%改成120%)来控制清晰区域的大小和模糊边缘的宽度。
方案二:伪元素+Filter模糊 —— 兼容性备选方案
如果需要兼容一些不支持mask的旧浏览器,可以用伪元素叠加模糊效果的思路:
修改后的CSS核心代码
.reveal { z-index: 5; position: absolute; width: 20rem; height: 20rem; border-radius: 50%; overflow: hidden; background: url("http://gallery.hd.org/_exhibits/textures/text-sample-of-old-novel-DHD.jpg") 50% 50% no-repeat fixed; background-size: cover; } .reveal::after { content: ''; position: absolute; top: -20%; left: -20%; width: 140%; height: 140%; border-radius: 50%; /* 用模糊滤镜实现边缘渐变 */ filter: blur(1.5rem); /* 径向渐变让中心透明,边缘半透明覆盖 */ background: radial-gradient(circle, transparent 60%, rgba(0,0,0,1) 100%); pointer-events: none; /* 不干扰鼠标事件 */ }
原理说明
.reveal本身是圆形的清晰图片区域,伪元素::after覆盖在上面,用blur滤镜和径向渐变,让边缘产生模糊的遮罩效果,模拟渐变过渡。
方案三:Canvas实现 —— 自定义模糊效果
如果需要更精细的控制(比如自定义模糊曲线、动态调整模糊程度),Canvas是最佳选择,虽然代码稍复杂,但灵活性极强:
示例代码
<div class="background"> <canvas id="revealCanvas"></canvas> </div>
html, body { font-size: 62.5%; height: 100%; overflow: hidden; margin: 0; } .background { position: relative; height: 100%; background: #000; background: url("http://www.wallpapers4u.org/wp-content/uploads/paper_patterns_backgrounds_textures_lines_36212_1920x1080.jpg") 50% 50% no-repeat fixed; background-size: cover; } #revealCanvas { position: absolute; z-index: 5; pointer-events: none; }
document.addEventListener('DOMContentLoaded', function() { const canvas = document.getElementById('revealCanvas'); const ctx = canvas.getContext('2d'); const revealSize = 200; // 圆形窗口大小 const blurRadius = 30; // 模糊边缘宽度 // 设置canvas尺寸 canvas.width = window.innerWidth; canvas.height = window.innerHeight; // 加载要显示的图片 const revealImg = new Image(); revealImg.src = "http://gallery.hd.org/_exhibits/textures/text-sample-of-old-novel-DHD.jpg"; revealImg.onload = function() { document.addEventListener('mousemove', function(e) { ctx.clearRect(0, 0, canvas.width, canvas.height); // 先绘制模糊的背景层 ctx.filter = `blur(${blurRadius}px)`; ctx.drawImage(revealImg, e.pageX - revealSize/2 - blurRadius, e.pageY - revealSize/2 - blurRadius, revealSize + blurRadius*2, revealSize + blurRadius*2); // 再绘制清晰的中心圆形区域 ctx.filter = 'none'; ctx.globalCompositeOperation = 'destination-in'; ctx.beginPath(); ctx.arc(e.pageX, e.pageY, revealSize/2, 0, Math.PI*2); ctx.fill(); // 恢复合成模式 ctx.globalCompositeOperation = 'source-over'; }); }; });
原理说明
- 先绘制一张模糊的图片区域,然后用
destination-in合成模式,只保留圆形范围内的内容,这样边缘就自然带有模糊效果。 - 你可以通过调整
blurRadius和revealSize来精确控制模糊程度和窗口大小。
内容的提问来源于stack exchange,提问作者dlarkiddo
相关产品推荐
相关产品推荐

