鼠标悬停/移出时带过渡效果的SVG Filter动画实现问题
正确实现带过渡效果的SVG Filter动画方案
原有代码问题分析
- 用
<use>标签复用<animate>元素的写法不符合SVG规范,无法生效 - 鼠标移出时直接清空filter属性,会导致退出动画还未执行就丢失滤镜效果,看不到过渡动画
<animate>元素未设置fill="freeze",动画结束后属性值会回弹到初始状态,无法保持动画最终效果
完整实现代码
HTML代码
<svg width="400" height="400"> <defs> <filter id="filter"> <feGaussianBlur in="SourceGraphic" stdDeviation="0"> <!-- 悬停进入动画:模糊从0到10 --> <animate id="startA" attributeName="stdDeviation" values="0;10" dur="1s" fill="freeze"></animate> <!-- 悬停退出动画:模糊从10到0 --> <animate id="stopA" attributeName="stdDeviation" values="10;0" dur="1s" fill="freeze"></animate> </feGaussianBlur> <feMerge> <feMergeNode/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> </defs> <!-- 初始就绑定滤镜,默认模糊为0无视觉效果 --> <rect x="50" y="50" width="180" height="180" fill="#4a8" filter="url(#filter)"></rect> </svg>
JS代码
const rect = document.querySelector("rect") const startAni = document.querySelector("#startA") const stopAni = document.querySelector("#stopA") rect.addEventListener("mouseover", () => { startAni.beginElement() }) rect.addEventListener("mouseleave", () => { stopAni.beginElement() })
可选简化方案:纯CSS实现
如果不需要复杂的动画时序控制,用CSS过渡实现更简洁:
/* 注册自定义变量才能支持过渡效果 */ @property --blur { syntax: "<number>"; inherits: true; initial-value: 0; } rect { filter: url(#blurFilter); transition: --blur 1s; } rect:hover { --blur: 10; }
<svg width="400" height="400"> <defs> <filter id="blurFilter"> <feGaussianBlur in="SourceGraphic" stdDeviation="var(--blur, 0)"/> <feMerge> <feMergeNode/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> </defs> <rect x="50" y="50" width="180" height="180" fill="#4a8"></rect> </svg>
内容的提问来源于stack exchange,提问作者Enes Giray
相关产品推荐
相关产品推荐

