【问题标题】:Animate SVG straight line by CSS transition通过 CSS 过渡动画 SVG 直线
【发布时间】:2021-02-06 03:07:14
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您可以使用 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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-16
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 2018-04-20
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        相关资源
        最近更新 更多