【问题标题】:JavaScript SVGLine connecting moving elements animationJavaScript SVGLine 连接移动元素动画
【发布时间】:2021-11-27 02:48:59
【问题描述】:

我有两个 SVG 矩形;它们的两个角由 SVGLine 连接,我正在尝试为整体设置动画。

现在矩形正在使用 Element.animate() 函数移动到一个新位置(新位置必须在运行时计算,所以我认为只有在 JS 中使用 animate() 函数才有可能?)。
在那之前一切正常,但是当我尝试为线设置动画以使其在动画期间仍连接角时,它不会移动。
有什么方法可以将线条移动到新位置? (我不能只将属性设置为新位置)。

如果我必须使用 <path><polyline> 或其他东西来快速解释我应该如何做会很好,因为 path.animate([{points:...},{points:...}],{...}) 也没有按照我的意愿移动路径。

这是一个我认为应该可以工作的快速代码示例,但行不会移动。

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: '200px'
  }], {
    duration: 5000,
    iterations: 1
  });
  rect2.animate([{
    y: rect2.y.baseVal.value
  }, {
    y: '300px'
  }], {
    duration: 5000,
    iterations: 1
  });

  line.animate([{
    x1: line.x1.baseVal.value,
    y2: line.y2.baseVal.value
  }, {
    x1: '200px',
    y2: '300px'
  }], {
    duration: 5000,
    iterations: 1
  });
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>

【问题讨论】:

    标签: javascript svg


    【解决方案1】:

    您只能animate() CSS 属性。在 SVG 中,只有 presentational attributes 映射到 CSS。 &lt;line&gt;x1,x2,y1y2 (奇怪地)不在此列表中...

    您应该可以用&lt;path&gt; 替换此元素,为其d 属性设置动画。

    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, "path");
      line.setAttribute("d", `
        M${ rect.x.baseVal.value } ${ rect.y.baseVal.value }
        L${ rect2.x.baseVal.value } ${ rect2.y.baseVal.value }
      `);
      line.setAttribute("stroke", "darkgray");
      svg.appendChild(line);
    
      rect.animate([{
        x: '200px'
      }], {
        duration: 5000,
        iterations: 1
      });
      rect2.animate([{
        y: '300px'
      }], {
        duration: 5000,
        iterations: 1
      });
    
      line.animate([{
        d: `path("M200 ${ rect.y.baseVal.value }L${ rect2.x.baseVal.value } 300")`
      }], {
        duration: 5000,
        iterations: 1
      });
    }
    drawing();
    <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
    </svg>

    但只有基于 Chromium 的浏览器支持 CSS path() d 属性...

    所以你可能不得不改用SMIL animations

    let svg = document.querySelector("#theSVG");
    const SVGNS = "http://www.w3.org/2000/svg";
    
    function drawing() {
      const 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);
      const rectAnimateX = document.createElementNS(SVGNS, "animate");
      rectAnimateX.setAttribute("attributeName", "x");
      rectAnimateX.setAttribute("values", "100;200");
      rectAnimateX.setAttribute("dur", "5s");
      rect.append(rectAnimateX);
      
      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);
      const rectAnimateY = document.createElementNS(SVGNS, "animate");
      rectAnimateY.setAttribute("attributeName", "y");
      rectAnimateY.setAttribute("values", "10;300");
      rectAnimateY.setAttribute("dur", "5s");
      rect2.append(rectAnimateY);
    
      const line = document.createElementNS(SVGNS, "line");
      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);
      line.setAttribute("stroke", "darkgray");
      svg.appendChild(line);
      const lineAnimateX1 = document.createElementNS(SVGNS, "animate");
      lineAnimateX1.setAttribute("attributeName", "x1");
      lineAnimateX1.setAttribute("values", `${rect.x.baseVal.value};200`);
      lineAnimateX1.setAttribute("dur", "5s");
      line.append(lineAnimateX1);
      const lineAnimateY2 = document.createElementNS(SVGNS, "animate");
      lineAnimateY2.setAttribute("attributeName", "y2");
      lineAnimateY2.setAttribute("values", `${rect2.y.baseVal.value};300`);
      lineAnimateY2.setAttribute("dur", "5s");
      line.append(lineAnimateY2);
    }
    drawing();
    <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
    </svg>

    【讨论】:

    • 感谢您的回答。 SMIL 动画对我有用。
    猜你喜欢
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多