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

如何基于SVG文本元素自身尺寸实现平移动画?滚动适配问题

解决SVG文本跑马灯动画基于自身尺寸的问题

SVG里的<text>用CSS transform的百分比确实坑——它是按父元素尺寸算的,不是文本自己的长度。给你几个靠谱的解决办法:

方法1:JS算文本宽度 + CSS变量联动

核心思路是先拿到文本的实际宽度,把这个值存成CSS变量,动画里直接用这个变量来算偏移量,精准匹配文本长度。

调整后的CSS:

.title {
  animation-name: overflow-scroll;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  max-width: none;
}
@keyframes overflow-scroll{
  0% { transform: translateX(0); }
  100% { transform: translateX(calc(-1 * var(--text-width))); }
}

补充JS逻辑(文本渲染后执行):

等API返回的文本渲染到SVG里之后,用getBBox()拿到文本的真实宽度,把它设成元素的CSS变量:

// 假设你的text元素能通过.title选中
const titleEl = document.querySelector('.title');
if (titleEl && titleData.length > 22) {
  const textWidth = titleEl.getBBox().width;
  titleEl.style.setProperty('--text-width', `${textWidth}px`);
}

如果是React/Vue这类框架,就把这段逻辑放到数据更新后的钩子(比如React的useEffect,依赖titleData)里,确保文本渲染完再计算。

方法2:用SVG原生元素

SVG自带的动画元素可以直接基于自身边界计算,避开CSS transform的百分比坑。

修改你的SVG生成代码:

<svg>
  <defs>
    <style>
      { titleData.length > 22 ? ".title { white-space: nowrap; }" : "" }
    </style>
  </defs>

  <text x="80" y="37" className="title" {...titleStyle}>
    <tspan>{titleData}</tspan>
    { titleData.length > 22 && <tspan>{titleData}</tspan>}
    { titleData.length > 22 && (
      <animate
        attributeName="x"
        from="80"
        to={80 - titleEl.getBBox().width}
        dur="10s"
        repeatCount="indefinite"
        calcMode="linear"
      />
    )}
  </text>
</svg>

同样要先算好文本宽度,把to属性设成初始x值减去文本宽度,这样动画会精确移动一个文本长度,完美循环。

方法3:双文本拼接 + 移动50%(懒人兼容方案)

如果不想写JS计算,也可以换个思路:你已经把文本拼了两次,那动画里直接移动-50%就行——因为双文本总长度是单文本的两倍,移动50%刚好让第二个文本接在第一个后面,视觉上实现循环。前提是你的SVG容器宽度固定,且文本长度超过容器。

调整动画:

@keyframes overflow-scroll{
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

这个方法简单,但灵活性差,适合容器宽度固定的场景。


内容的提问来源于stack exchange,提问作者Exodius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:55:02