Надеюсь, я понял ваш вопрос: если вы хотите анимировать от одной кривой к другой, вы можете использовать анимацию 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>