如何为CSS遮罩(mask)添加过渡动画效果
如何为CSS遮罩(mask)添加过渡动画效果
嘿,我懂你想要实现那种鼠标移动时遮罩平滑跟随的过渡效果,咱们来看看你当前代码的问题,以及怎么调整才能达到预期~
首先说核心问题:你给:root里的自定义属性加了过渡,但因为变量值是带%的字符串,CSS没法正确识别这种类型的变化来触发过渡;另外,过渡的位置也不对,应该作用在实际使用遮罩的元素上,而不是变量的定义处。
咱们来一步步修改:
1. 调整JavaScript代码,传递数值而非带单位的字符串
把鼠标位置计算改成0-100之间的纯数值,这样CSS能正确处理过渡:
const cursor = document.querySelector('.hero'); cursor.addEventListener('mousemove', (event) => { const rect = cursor.getBoundingClientRect(); // 计算0到100的纯数值,不带百分比单位 const mouseX = ((event.clientX - rect.left) / rect.width) * 100; const mouseY = ((event.clientY - rect.top) / rect.height) * 100; document.documentElement.style.setProperty('--mouse-x', mouseX); document.documentElement.style.setProperty('--mouse-y', mouseY); });
2. 修改CSS,让过渡作用在遮罩元素上
去掉:root里的过渡,转而给遮罩元素的mask-image属性加过渡(还要考虑webkit前缀兼容),同时用calc()把数值转成百分比:
:root { --mouse-x: 0; --mouse-y: 0; /* 这里不需要过渡,把过渡逻辑放在实际使用变量的元素上 */ } .co-pattern__overlay { position: absolute; inset: 0; /* 替代top/right/bottom/left:0,写法更简洁 */ width: 100%; height: 100%; pointer-events: none; background-color: #0f1218; z-index: 1; /* 针对遮罩图像添加过渡,确保位置变化时平滑动画 */ transition: mask-image 0.3s ease, -webkit-mask-image 0.3s ease; } .co-pattern__overlay { mask: radial-gradient(circle at calc(var(--mouse-x) * 1%) calc(var(--mouse-y) * 1%), transparent 20px, black 350px); -webkit-mask: radial-gradient(circle at calc(var(--mouse-x) * 1%) calc(var(--mouse-y) * 1%), transparent 20px, black 350px); }
3. HTML保持不变
<div class="hero"> <div class="co-pattern__overlay"></div> </div>
为什么这样改能生效?
- 自定义属性用纯数值时,CSS可以识别数值的连续变化,从而正确触发过渡动画
- 把过渡作用在
mask-image上,直接针对遮罩的渐变属性,避免了复合属性mask过渡支持不佳的问题 - 用
calc(var(--mouse-x) * 1%)把数值转成百分比,既保留了变量的数值特性,又满足了CSS位置的单位需求
这样调整后,鼠标移动时遮罩的圆形透明区域就会平滑跟随,达到你想要的过渡效果啦~
备注:内容来源于stack exchange,提问作者stemon
相关产品推荐
相关产品推荐

