【问题标题】:Javascript SVG curve change path attirbut CJavascript SVG曲线改变路径属性C
【发布时间】:2020-10-29 06:07:50
【问题描述】:

提前谢谢你。
我尝试使用 javascript 在 html 中移动 un SVG 曲线元素。
我想改变我的 svg 的路径,使我的蓝色曲线像红色曲线一样变换,但通过过渡可以看到曲线的位移。 我了解如何获取或创建元素,但我不确定如何设置属性“d”,例如更改路径中的每个“c”。

alert(document.getElementById('s3').getAttribute('d'));
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>


    <svg viewBox="0 0 990 180" height="200" width="1100" id="mySVG">

        <g> 
            <path id="s2" d="M 241,128 C 272,113 293,152 369,125 C 434,80 471,72 580,114  " 
            fill="none" stroke="red" stroke-width="5px" />

            <path id="s3" d="M 241,128 C266,131 298,100 369,125 C 441,150 482,151 580,114  " 
            fill="none" stroke="blue" stroke-width="5px" />
           

        </g>

    </svg>
    <script src="app.js"></script>
</body>
</html>

【问题讨论】:

    标签: javascript svg path attributes set


    【解决方案1】:

    希望我能理解您的问题:如果您想从一条曲线动画到另一条曲线,您可以使用 SMIL 动画。

    由于代码中的路径具有相同数量和相同类型的命令,您可以使用&lt;animate&gt; 元素为 d 属性设置动画。

    values 属性是一个用分号 (;) 分隔的值列表。第一个和最后一个值是曲线的 d 属性。第二个值是另一个的d属性。

    在我的代码中,动画的持续时间是 5 秒:dur="5s

    <svg viewBox="235 80 350 70" width="300" id="mySVG">
    
      <g>
        <path id="s2" d="M 241,128 
                 C 272,113 293,152 369,125 
                 C 434,80 471,72 580,114" fill="none" stroke="red" stroke-width="5px">
    
        </path>
    
        <path id="s3" d="M 241,128 
                 C266,131 298,100 369,125 
                 C 441,150 482,151 580,114" fill="none" stroke="blue" stroke-width="5px">
          <animate attributeName="d" attributeType="XML" values="M 241,128 
                 C266,131 298,100 369,125 
                 C 441,150 482,151 580,114;    
                     
                 M 241,128 
                 C 272,113 293,152 369,125 
                 C 434,80 471,72 580,114;
                     
                 M 241,128 
                 C266,131 298,100 369,125 
                 C 441,150 482,151 580,114; " dur="5s" repeatCount="indefinite" />
        </path>
    
      </g>
    </svg>

    更新

    OP 正在评论:

    我可以用javascript制作吗?

    用 javascript 制作更复杂。您将需要设置一个值数组和一个目标值数组,并使用动画的每一帧重新计算曲线的每个值。接下来是一个在点击时为蓝色曲线设置动画的示例:

    请阅读代码中的cmets。

    //I've hard coded the values and the target array
    //you may want to do it dimamicaly from the d attribute
    
    let vals = [
      ["M", 241, 128],
      ["C", 272, 113, 293, 152, 369, 125],
      ["C", 434, 80, 471, 72, 580, 114]
    ];
    
    let target = [
      ["M", 241, 128],
      ["C", 266, 131, 298, 100, 369, 125],
      ["C", 441, 150, 482, 151, 580, 114]
    ];
    
    //the request animation id
    let rid = null;
    //build the memory array used for the animation
    let memory = [];
    for (let i = 0; i < vals.length; i++) {
      memory[i] = [];
      memory[i][0] = target[i].slice();
      memory[i][1] = vals[i].slice();
    }
    
    function Frame() {
      rid = window.requestAnimationFrame(Frame);
      updateValues();
      updatePath();
    }
    
    window.addEventListener("load", updatePath, false);
    
    
    // I'm animating the curve on click
    svg.addEventListener(
      "mousedown",
      function () {
      // if there is an animation running stop it before start another one
        if (rid) {
          window.cancelAnimationFrame(rid);
          rid = null;
        }
        
        //reverse the animation
        for (let i = 0; i < memory.length; i++) {
          memory[i].reverse();
          target[i] = memory[i][1].slice();
        }
        //call the Frame function
        Frame();
      },
      false
    );
    
    function updateValues() {
    //a function to update all the values of the curve except the move to part that is not changing anyway
      for (let i = 1; i < vals.length; i++) {
        for (let j = 1; j < vals[i].length; j++) {
          let dist = target[i][j] - vals[i][j];
          let vel = dist / 10;
          vals[i][j] += vel;
        }
      }
    }
    //a function to reset the value of the d attribute
    function updatePath() {
      let d = `M${vals[0][1]},${vals[0][2]}`;
      for (let i = 1; i < vals.length; i++) {
        d += `C${vals[i][1]},${vals[i][2]},${vals[i][3]},${vals[i][4]},${vals[i][5]},${vals[i][6]}`;
      }
      s3.setAttributeNS(null, "d", d);
    }
    svg{border:1px solid}
    <svg id="svg" viewBox="235 80 350 70" width="300" id="mySVG">
      <g>
        <path id="s2" d="M 241,128 
                 C 272,113 293,152 369,125 
                 C 434,80 471,72 580,114" fill="none" stroke="red" stroke-width="5px">
        </path>
        <path id="s3" d="M 241,128 
                 C266,131 298,100 369,125 
                 C 441,150 482,151 580,114" fill="none" stroke="blue" stroke-width="5px">    
        </path>
      </g>
    </svg>

    【讨论】:

    • 感谢您提供此解决方案,但我可以用 javascript 制作吗?
    • 非常感谢,这正是我想要的,我开始以这种方式创造一些东西,但完美的工作。
    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2018-06-02
    • 2011-09-17
    • 2017-04-10
    • 2019-12-31
    • 1970-01-01
    相关资源
    最近更新 更多