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

如何使用JS Element.animate()实现SVG连接线随移动矩形同步动画

问题原因
  • SVG坐标类属性(x、y、x1、y1、x2、y2等)默认使用viewBox下的无单位用户坐标,你在动画关键帧里给值加了px单位,导致Web Animations API无法正确识别属性值类型,因此线条没有触发动画。
  • 如果矩形的最终位置是运行时动态计算的,预先写死线条的关键帧会不够灵活,更推荐逐帧同步端点坐标的方案。
直接修复原有代码

去掉关键帧里的px单位即可,可额外添加fill: 'forwards'让元素动画结束后停在最终位置:

<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";

function drawing() {
  let rect = document.createElementNS(SVGNS, "rect");
  rect.setAttribute("x", 100);
  rect.setAttribute("y", 100);
  rect.setAttribute("width", 100);
  rect.setAttribute("height", 100);
  rect.setAttribute("stroke", "black");
  svg.appendChild(rect);

  let rect2 = document.createElementNS(SVGNS, "rect");
  rect2.setAttribute("x", 10);
  rect2.setAttribute("y", 10);
  rect2.setAttribute("width", 50);
  rect2.setAttribute("height", 25);
  rect2.setAttribute("stroke", "black");
  svg.appendChild(rect2);

  let line = document.createElementNS(SVGNS, "line");
  line.setAttribute("x1", rect.x.baseVal.value);
  line.setAttribute("x2", rect2.x.baseVal.value);
  line.setAttribute("y1", rect.y.baseVal.value);
  line.setAttribute("y2", rect2.y.baseVal.value);
  line.setAttribute("stroke", "darkgray");
  svg.appendChild(line);

  rect.animate([{
    x: rect.x.baseVal.value
  }, {
    x: 200
  }], {
    duration: 5000,
    iterations: 1,
    fill: 'forwards'
  });
  rect2.animate([{
    y: rect2.y.baseVal.value
  }, {
    y: 300
  }], {
    duration: 5000,
    iterations: 1,
    fill: 'forwards'
  });

  line.animate([{
    x1: line.x1.baseVal.value,
    y2: line.y2.baseVal.value
  }, {
    x1: 200,
    y2: 300
  }], {
    duration: 5000,
    iterations: 1,
    fill: 'forwards'
  });
}
drawing();
动态同步方案(适合矩形位置运行时计算的场景)

不需要预先给线条写关键帧,通过requestAnimationFrame逐帧读取矩形的当前动画位置,同步给线条端点即可,不管矩形后续运动逻辑怎么改,线条都会自动跟上:

// 接上面的drawing函数,把原来的line.animate部分替换成下面的代码
function syncLine() {
  line.setAttribute('x1', rect.x.baseVal.value);
  line.setAttribute('y1', rect.y.baseVal.value);
  line.setAttribute('x2', rect2.x.baseVal.value);
  line.setAttribute('y2', rect2.y.baseVal.value);
  requestAnimationFrame(syncLine);
}
syncLine();
path/polyline实现说明
  • 使用<polyline>时直接对points属性做动画,值为空格分隔的坐标对,不需要加单位,两个关键帧的坐标点数量要一致才能平滑过渡:
polyline.animate([
  {points: "100 100 10 10"},
  {points: "200 100 10 300"}
], {
  duration: 5000,
  fill: 'forwards'
})
  • 使用<path>时直接对d属性做动画,同样要求两个关键帧的路径结构完全一致,仅坐标值不同:
path.animate([
  {d: "M 100 100 L 10 10"},
  {d: "M 200 100 L 10 300"}
], {
  duration: 5000,
  fill: 'forwards'
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:57:02