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

animateMotion的fill="freeze"属性在Chrome浏览器中无法正常生效

SVG animateMotion 在 Chrome 中动画结束后复位的兼容性问题

我之前也踩过这个Chrome的SVG动画坑!你编写的这段SVG代码在Firefox 60.0.1里能正常让<path>停留在<animateMotion>动画的结束位置,但到了Chrome 65.0.3325.146中,动画结束后元素就会跳回初始位置。

问题代码示例

<svg xmlns="http://www.w3.org/2000/svg" style="padding: 100px;" > 
  <g> 
    <animateMotion path="M70 -48 C70 -48 136 136 230 166 M230 166 C324 196 472 370 460 470" 
                   keyPoints="0;0;0.407;1" 
                   keyTimes="0;0;0.383;1" 
                   keySplines="0.5,0.5,0.5,0.5;0.167 0.167 0.833 0.833;0.167 0.167 0.833 0.833" 
                   dur="2" 
                   fill="freeze" 
                   calcMode="spline" /> 
    <path fill="rgba(49, 187, 174, 1)" fill-opacity="1" d=" M37,17 C37,17 12.5,40.5 39,63 C65.5,38 37,17 37,17z"></path> 
  </g> 
</svg>

两种可行的解决方案

方案1:把动画直接绑定到目标<path>元素上

Chrome对容器元素(比如<g>)上的animateMotion的fill="freeze"支持有bug,把动画直接加到<path>上就能解决这个问题,Firefox也能正常兼容:

<svg xmlns="http://www.w3.org/2000/svg" style="padding: 100px;" > 
  <path fill="rgba(49, 187, 174, 1)" fill-opacity="1" d=" M37,17 C37,17 12.5,40.5 39,63 C65.5,38 37,17 37,17z">
    <animateMotion path="M70 -48 C70 -48 136 136 230 166 M230 166 C324 196 472 370 460 470" 
                   keyPoints="0;0;0.407;1" 
                   keyTimes="0;0;0.383;1" 
                   keySplines="0.5,0.5,0.5,0.5;0.167 0.167 0.833 0.833;0.167 0.167 0.833 0.833" 
                   dur="2" 
                   fill="freeze" 
                   calcMode="spline" /> 
  </path> 
</svg>

方案2:用JS强制锁定结束状态

如果必须保留<g>的结构,可以监听动画结束事件,手动把元素的变换状态设置为动画结束时的状态,避免Chrome复位:

const animateEl = document.querySelector('animateMotion');
const groupEl = document.querySelector('g');

animateEl.addEventListener('endEvent', () => {
  // 获取动画结束时的变换矩阵
  const finalTransform = groupEl.getCTM();
  // 把矩阵转换为transform属性值
  groupEl.setAttribute('transform', `matrix(${finalTransform.a}, ${finalTransform.b}, ${finalTransform.c}, ${finalTransform.d}, ${finalTransform.e}, ${finalTransform.f})`);
  // 移除动画元素,防止后续触发复位
  animateEl.remove();
});

问题根源

Chrome在处理容器元素上的animateMotion动画时,fill="freeze"的效果没有正确传递给子元素,动画结束后会重置容器的变换属性。而直接将动画绑定到目标元素上,浏览器就能正确识别并保留动画结束后的最终状态。

内容的提问来源于stack exchange,提问作者喵了个咪

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:11:17