Javascript SVG曲线更改路径属性C

时间:2020-07-08 18:32:53

标签: javascript svg path attributes set


预先谢谢你。
我尝试使用javascript在html中移动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>

1 个答案:

答案 0 :(得分:1)

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

由于代码中的路径具有相同的编号和相同的命令类型,因此可以使用<animate>元素为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制作起来更加复杂。您将需要设置一个值数组和一个目标值数组,并在动画的每一帧中重新计算曲线的每个值。接下来是一个使点击时的蓝色曲线动画的示例:

请阅读代码中的注释。

//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>