通过 CSS 过渡动画 SVG 直线

Animate SVG straight line by CSS transition

我想以同样的方式移动直线和圆圈,并用 CSS 设置动画过渡。
对圆起作用,对线不起作用

怎么了?

const state = {
  x: 75,
  y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];

setInterval(() => {
  state.x = Math.floor(Math.random() * 150);
  state.y = Math.floor(Math.random() * 150);
  line.setAttribute("x2", state.x);
  line.setAttribute("y2", state.y);
  circle.setAttribute("transform", `translate(${state.x} ${state.y})`);
}, 2000)
circle,
line {
  transition: all 1s ease;
}
<svg height="150" width="150" style="border: 1px solid black">
  <line 
    x1="0"
    y1="0"
    x2="75"
    y2="75"
    stroke="red"
  >
  </line>
  <circle 
    r="10"
    transform="translate(75 75)"
    fill="none"
    stroke="blue"
  >
  </circle>
</svg>

您可以使用 Path 元素代替 Line 元素,如下所示:

const state = {
  x: 75,
  y: 75
};
const line = document.getElementsByClassName('line')[0];

setInterval(() => {
  state.x = Math.floor(Math.random() * 150);
  state.y = Math.floor(Math.random() * 150);
  line.setAttribute("d", `M 0 0 l ${state.x} ${state.y}`);
}, 2000)
path {
  transition: all 1s ease;
}
<svg height="150" width="150" style="border: 1px solid black">
    <path
    class="line"
    d="M 0 0 L 75 75"
    stroke="red"
    fill="none"
    />
</svg>

使圆和线同步动画的最简单方法是将圆用作 marker

在这种情况下,圆圈将始终附加到直线上并随之移动。

const state = {
  x: 75,
  y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];

setInterval(() => {
  state.x = Math.floor(Math.random() * 150);
  state.y = Math.floor(Math.random() * 150);
  line.setAttribute("x2", state.x);
  line.setAttribute("y2", state.y);
 
}, 2000)
<svg height="160" width="160" style="border: 1px solid black"> 
<defs>
  <marker id="markEnd"  viewBox="0 0 22 22" refX="10" refY="10"  markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
  <circle r="10" cx="10" cy="10" fill="none"  stroke="blue" />
  </marker> 
</defs>
  <line 
    x1="0"
    y1="0"
    x2="75"
    y2="75"
    stroke="red" 
    marker-end="url(#markEnd)"
  >
  </line>
  
</svg>

更新

选项@AOD 用路径和标记替换行

const state = {
  x: 75,
  y: 75
};
const line = document.getElementsByClassName('line')[0];

setInterval(() => {
  state.x = Math.floor(Math.random() * 150);
  state.y = Math.floor(Math.random() * 150);
  line.setAttribute("d", `M 0 0 L ${state.x} ${state.y}`);
}, 2000)
path {
  transition: all 1s ease;
}
<svg height="160" width="160" style="border: 1px solid black"> 
<defs>
  <marker id="markEnd"  viewBox="0 0 22 22" refX="10" refY="10"  markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
  <circle r="10" cx="10" cy="10" fill="none"  stroke="blue" />
  </marker> 
</defs>
    <path
    class="line"
    d="M 0 0 L 75 75"
    stroke="red"
    fill="none"
    marker-end="url(#markEnd)"
    />
</svg>