实现深色背景下鼠标跟随渐变光斑及跨浏览器兼容问题
鼠标跟随彩虹渐变Blob效果实现与兼容问题解决
问题描述
- 目标效果:深色背景下,鼠标移动时光斑显示彩虹渐变色彩,其余区域保持暗色
- 当前实现问题:采用深色背景层、Blob层、渐变层、模糊层的分层方案,但渐变层未生效,仅能显示白色Blob+深色背景
- Safari兼容问题:光斑要么不显示、跟踪偏移,要么鼠标移动时重置位置
修正后的实现方案
1. 修复分层混合模式问题
原方案的分层顺序与混合模式搭配错误,调整后让渐变层仅在Blob区域显示:
body { background-color: #222020; height: 100vh; margin: 0; overflow: hidden; position: relative; } #gradient-color { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(50% 123.47% at 50% 50%, #00ff94 0%, #720059 100%), linear-gradient(121.28deg, #669600 0%, #ff0000 100%), linear-gradient(360deg, #0029ff 0%, #8fff00 100%), radial-gradient(100% 164.72% at 100% 100%, #6100ff 0%, #00ff57 100%), radial-gradient(100% 148.07% at 0% 0%, #fff500 0%, #51d500 100%); background-blend-mode: screen, color-dodge, overlay, difference, normal; z-index: 1; /* 关键:让渐变仅在白色Blob区域显示 */ mix-blend-mode: lighten; } #blob { height: 34vmax; aspect-ratio: 1; position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 50%; background-color: white; /* 作为遮罩层,过滤渐变显示区域 */ mix-blend-mode: multiply; z-index: 2; } #blur { height: 100%; width: 100%; position: fixed; z-index: 3; backdrop-filter: blur(12vmax); -webkit-backdrop-filter: blur(12vmax); /* Safari前缀兼容 */ mix-blend-mode: darken; }
2. Safari浏览器兼容修复
Safari对animate()方法的fill: forwards支持存在问题,改用requestAnimationFrame实现平滑跟踪:
const blob = document.getElementById("blob"); let mouseX = window.innerWidth / 2; let mouseY = window.innerHeight / 2; // 帧动画实现平滑缓动跟踪 function updateBlob() { const blobWidth = blob.offsetWidth; const blobHeight = blob.offsetHeight; const targetX = mouseX - blobWidth / 2; const targetY = mouseY - blobHeight / 2; // 缓动公式,调整0.1可改变跟踪灵敏度 blob.style.left = `${parseFloat(blob.style.left || targetX) + (targetX - parseFloat(blob.style.left || targetX)) * 0.1}px`; blob.style.top = `${parseFloat(blob.style.top || targetY) + (targetY - parseFloat(blob.style.top || targetY)) * 0.1}px`; requestAnimationFrame(updateBlob); } window.addEventListener("pointermove", (e) => { mouseX = e.clientX; mouseY = e.clientY; }); // 初始化位置 blob.style.left = `${mouseX - blob.offsetWidth / 2}px`; blob.style.top = `${mouseY - blob.offsetHeight / 2}px`; updateBlob();
替代简化方案
如果觉得分层方案复杂,可直接用CSS遮罩+模糊实现,减少层级:
body { background-color: #222020; height: 100vh; margin: 0; overflow: hidden; position: relative; } #gradient-blob { height: 34vmax; aspect-ratio: 1; position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(50% 123.47% at 50% 50%, #00ff94 0%, #720059 100%), linear-gradient(121.28deg, #669600 0%, #ff0000 100%), linear-gradient(360deg, #0029ff 0%, #8fff00 100%), radial-gradient(100% 164.72% at 100% 100%, #6100ff 0%, #00ff57 100%), radial-gradient(100% 148.07% at 0% 0%, #fff500 0%, #51d500 100%); background-blend-mode: screen, color-dodge, overlay, difference, normal; filter: blur(12vmax); opacity: 0.8; }
JavaScript部分使用上述兼容版的跟踪代码即可,仅需一个元素就能实现目标效果。
内容的提问来源于stack exchange,提问作者soupbin
相关产品推荐
相关产品推荐

