我的SVG贝塞尔曲线能否实现波浪效果?

3
我正在尝试给我的线条添加波浪效果。

<svg width="1440" height="768" viewBox="0 0 1440 768" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M-83.6143 -168.119C-83.6143 -168.119 -28.2399 30.8053 74.4593 88.0896C221.086 169.876 364.03 -134.373 489.568 -22.8989C541.227 22.9737 522.397 86.2632 573.454 132.805C668.648 219.579 808.738 68.6733 902.337 157.164C984.353 234.705 886.122 360.221 967.307 438.631C1076.34 543.937 1234.26 326.531 1354.83 418.414C1480.33 514.051 1274.03 778.862 1427.47 815.613C1487.58 830.013 1584.35 794.881 1584.35 794.881" stroke="#979F79" stroke-width="2">
 </path>
</svg>

但我不知道哪种方法是正确的。 猜想,我需要从js改变起始和结束点。

非常感谢。


起点为M-83.6143 -168.119,终点为1584.35 794.881。(希望这能有所帮助) - evolutionxbox
Evolutionxbox 是正确的。尝试使用这个代替:viewBox="-83 -168 1668 987" - enxaneta
@enxaneta 我想得到类似于wavify的东西,但我不知道它是如何工作的。 - Solar system
@evolutionxbox 我想要得到类似于wavify的东西,但我不知道它是如何工作的。 - Solar system
你能提供一个期望的输出吗?例如简单的动画gif形式? - Jan Stránský
@JanStránský https://codepen.io/manabox/pen/BPrNPg 就像那样。但是不要只有填充,只有描边2px。 - Solar system
2个回答

5
为了确保SVG曲线不超出SVG画布,需要精确计算其整体尺寸。可以使用JS的getBBox()方法来实现。

let bb = wave.getBBox();

console.log(bb);
<svg width="1440" height="768" viewBox="0 0 1440 768" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="wave" d="M-83.6143 -168.119C-83.6143 -168.119 -28.2399 30.8053 74.4593 88.0896C221.086 169.876 364.03 -134.373 489.568 -22.8989C541.227 22.9737 522.397 86.2632 573.454 132.805C668.648 219.579 808.738 68.6733 902.337 157.164C984.353 234.705 886.122 360.221 967.307 438.631C1076.34 543.937 1234.26 326.531 1354.83 418.414C1480.33 514.051 1274.03 778.862 1427.47 815.613C1487.58 830.013 1584.35 794.881 1584.35 794.881" stroke="#979F79" stroke-width="2">
  </path>
 </svg> 

将得到的数字添加到viewBox中。
原来的值为viewBox="0 0 1440 768",现在变为viewBox="-83 -168 1668 987"

<svg width="1440" height="768" viewBox="-83 -168 1668 987" fill="none" xmlns="http://www.w3.org/2000/svg">

<path id="wave" d="M-83.6143 -168.119C-83.6143 -168.119 -28.2399 30.8053 74.4593 88.0896C221.086 169.876 364.03 -134.373 489.568 -22.8989C541.227 22.9737 522.397 86.2632 573.454 132.805C668.648 219.579 808.738 68.6733 902.337 157.164C984.353 234.705 886.122 360.221 967.307 438.631C1076.34 543.937 1234.26 326.531 1354.83 418.414C1480.33 514.051 1274.03 778.862 1427.47 815.613C1487.58 830.013 1584.35 794.881 1584.35 794.881" stroke="#979F79" stroke-width="2">

    </path>
</svg>  

逐步获取d path属性动画的技巧

  1. 将SVG文件加载到矢量编辑器(如Inkscape)中
  2. 选择路径并克隆它

enter image description here

注意

为了使动画运行平滑无跳跃,起始和结束位置的节点数和类型必须相同。

克隆曲线是实现这个条件最简单的方法。

enter image description here

3. 要更改曲线克隆,请更改节点点的位置(在图中为红色曲线)。
4. 在矢量编辑器中保存文件。
5. 复制曲线起始和结束位置的补丁。
6. d 属性的动画是从起始位置移动到结束位置。
更新
如果您希望从起始位置重复动画到最终位置,然后返回到起始位置: values="path-start;path-finish;path-start"

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="1440" height="768" viewBox="-83 -168 1668 987" fill="none" version="1.1" border="1">
  <path d="M-83.6-168.1C-83.6-168.1-28.2 30.8 74.5 88.1 221.1 169.9 364-134.4 489.6-22.9 541.2 23 522.4 86.3 573.5 132.8 668.6 219.6 808.7 68.7 902.3 157.2 984.4 234.7 886.1 360.2 967.3 438.6 1076.3 543.9 1234.3 326.5 1354.8 418.4 1480.3 514.1 1274 778.9 1427.5 815.6 1487.6 830 1584.4 794.9 1584.4 794.9" stroke="#979F79"  fill="none" stroke-width="2">
    <animate
      attributeName="d"
      dur="5s"
      begin="0s"
      repeatCount="indefinite"
      values ="
        M-83.6-168.1C-83.6-168.1-28.2 30.8 74.5 88.1 221.1 169.9 364-134.4 489.6-22.9 541.2 23 522.4 86.3 573.5 132.8 668.6 219.6 808.7 68.7 902.3 157.2 984.4 234.7 886.1 360.2 967.3 438.6 1076.3 543.9 1234.3 326.5 1354.8 418.4 1480.3 514.1 1274 778.9 1427.5 815.6 1487.6 830 1584.4 794.9 1584.4 794.9;
        
        m-78.8 87.9c0 0 171-311.8 255.7-230.2 124.2 119.8 84.8 203 207.1 230.2 140.8 0 99.3-262.4 265.6-179.1 199.2 49.5 254.4-56.1 316.7-1.2 89.6 31.1-70.6 478.5 36.2 515 149 50.9 195-20.9 315.5 71 125.5 95.6-26.4 245.3 127 282 60.1 14.4 139.3 19.3 139.3 19.3;
        
        M-83.6-168.1C-83.6-168.1-28.2 30.8 74.5 88.1 221.1 169.9 364-134.4 489.6-22.9 541.2 23 522.4 86.3 573.5 132.8 668.6 219.6 808.7 68.7 902.3 157.2 984.4 234.7 886.1 360.2 967.3 438.6 1076.3 543.9 1234.3 326.5 1354.8 418.4 1480.3 514.1 1274 778.9 1427.5 815.6 1487.6 830 1584.4 794.9 1584.4 794.9"
        />
        
  </path>

  <!-- <path d="m-83.6-168.1c0 0 55.4 85.3 158.1 142.6 146.6 81.8 289.6-222.5 415.1-111 51.7 45.9 30.5 67.5 81.6 114 95.2 86.8 239.1-120 332.7-31.5 82 77.5-19.4 337.4 61.8 415.8 109 105.3 270.4-206.5 390.9-114.6 125.5 95.6-83.1 331.7 70.4 368.4 60.1 14.4 157.3 179.2 157.3 179.2" style="fill:none;stroke-width:2;stroke:#f00c79"/> -->
</svg>

你可以根据自己的喜好改变最终位置曲线的形状。
希望这个答案能帮到你。

如果我想创建像这样的波浪,我需要做什么?我必须从保存的SVG文件中获取坐标,路径,d属性或路径>动画标记>值吗? - Solar system
@Solarsystem 你需要将坐标替换为最终曲线路径的values(m-78.8 87.9c ... 19.3;)属性中,就像我的示例一样。你会有不同于你保存文件中的值。其余部分与示例完全相同。 - Alexandr_TT

3

另一个d属性动画的例子

这是另一种看起来更像波浪的路径形式。

获得最终路径的技术与第一个示例中相同。

  1. 开始路径

* {
padding:0;
margin:0;
}
body {
background:greenyellow;
}
<div class="morph-shape" id="morph-shape"  >
<svg xmlns="http://www.w3.org/2000/svg" width="200%" height="100%" viewBox="0 0 1000 300" preserveAspectRatio="none">
<path fill="dodgerblue" d="M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 L500.00,0.00 L0.00,0.00 Z"/>
</svg>
</div>

  1. 结束路径

* {
padding:0;
margin:0;
}
body {
background:greenyellow;
}
<div class="morph-shape" id="morph-shape"  >
<svg xmlns="http://www.w3.org/2000/svg" width="200%" height="100%" viewBox="0 0 1000 300" preserveAspectRatio="none">
<path fill="dodgerblue" d="M0.00,49.98 C157.16,-41.94 281.88,148.52 500.00,49.98 L500.00,0.00 L0.00,0.00 Z;"/>
</svg>
</div>

波浪动画

* {
padding:0;
margin:0;
}
body {
background:greenyellow;
}
<div class="morph-shape" id="morph-shape"  >
<svg xmlns="http://www.w3.org/2000/svg" width="200%" height="100%" viewBox="0 0 1000 300"  preserveAspectRatio="none">
<path fill="dodgerblue" d="M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 L500.00,0.00 L0.00,0.00 Z">
  <animate
    attributeName="d"
    dur="7s"
    repeatCount="indefinite" 
  values=" 
    M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 L500.00,0.00 L0.00,0.00 Z;
    M0.00,49.98 C157.16,-41.94 281.88,148.52 500.00,49.98 L500.00,0.00 L0.00,0.00 Z;
    M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 L500.00,0.00 L0.00,0.00 Z" />
</path> 
</svg> 
</div>

更新

像这样。 但不要填充,只显示2像素的轮廓。

<svg xmlns="http://www.w3.org/2000/svg" width="200%" height="100%" viewBox="0 0 1000 300"  preserveAspectRatio="none">
<path fill="none" stroke="dodgerblue" stroke-width="2" d="M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 L500.00,0.00 L0.00,0.00 Z">
  <animate
    attributeName="d"
    dur="7s"
    repeatCount="indefinite" 
  values=" 
    M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 ;
    M0.00,49.98 C157.16,-41.94 281.88,148.52 500.00,49.98 ;
    M0.00,49.98 C149.99,150.00 271.49,-49.98 500.00,49.98 " />
</path> 
</svg> 


1
显然,OP希望它“没有填充,只有2像素描边”(最后一条评论)。 - enxaneta
1
@enxaneta 谢谢你,我查看了作者链接上的代码片段,里面有一个填充。加上填充后看起来更好。如果作者不需要填充,那么去掉也没问题。 - Alexandr_TT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接