You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

鼠标悬停/移出时带过渡效果的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:54:01