通过 CSS 过渡动画 SVG 直线

时间:2021-02-05 16:44:03

标签: css svg css-animations css-transitions svg-animate

我想以同样的方式移动线和圆,并用 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>

2 个答案:

答案 0 :(得分:2)

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

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>

答案 1 :(得分:2)

同步为圆和线设置动画的最简单方法是将圆用作 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>