需要为曲线填充 Svg 动画

Posted

技术标签:

【中文标题】需要为曲线填充 Svg 动画【英文标题】:Need To fill Svg Animation for a curve 【发布时间】:2017-10-03 13:56:16 【问题描述】:

我在 svg 中有一条曲线,需要在悬停时沿其路径填充曲线,有人可以帮忙吗?填充动画应该是另一种颜色,或者可以是相同的。我尝试使用动画标签,但它无效并且像任何东西一样填充。我的 SVG 路径如下所示。这是我的 Svg 代码,需要将此路径填充为 dashoffset。

<svg   viewBox="0 0 744.09449 159.44881">
    <path style="opacity:1;fill:#ded9d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1"
          d="m 18.929688,529.44141 c 1.140051,2.17164 1.739409,4.60197 1.74414,7.07226 -0.0033,2.41521 -0.575072,4.79339 -1.666016,6.92969 l 36.876954,0 c 17.101683,0 11.124297,14.78094 13.525192,34.92207 7.304679,27.32129 35.935342,38.13518 62.612922,41.73111 -1.5457,-2.42739 -4.33484,-7.94712 -4.33733,-10.8524 0.005,-3.11453 0.90166,-5.74434 2.66254,-8.27277 -23.30774,-1.1068 -29.8766,-7.34118 -39.33413,-22.29658 -4.829034,-11.35821 5.68082,-49.23338 -28.703413,-49.23338 z" transform="translate(0.5714286,1.42857)" id="path4471" />
</svg>

【问题讨论】:

你能加入你的动画尝试吗? 请编辑问题,cmets 中的代码不可读。 【参考方案1】:

您的 SVG 补丁代码超出了用户 viewport,因此您看不到曲线。 我使用 - svg-editor Peter Collingridge 优化了你的 SVG 代码

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
   viewBox="-50 540 372 80.4" >
<path id="path1" d="m18.9 529.4c1.1 2.2 1.7 4.6 1.7 7.1 0 2.4-0.6 4.8-1.7 6.9l36.9 0c17.1 0 11.1 14.8 13.5 34.9 7.3 27.3 35.9 38.1 62.6 41.7-1.5-2.4-4.3-7.9-4.3-10.9 0-3.1 0.9-5.7 2.7-8.3-23.3-1.1-29.9-7.3-39.3-22.3-4.8-11.4 5.7-49.2-28.7-49.2z"  style=" stroke:none; stroke-width:1; fill:#ded9d5; />  
</svg> 

您的代码绘制了一条闭合路径,因此使用stroke-dashoffset 属性的动画将沿着闭合路径绘制一条曲线。

下面的例子。动画的开始是当您将鼠标悬停在形状上时。

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
   viewBox="-50 540 372 80.4" >
  
  <path id="path1" d="m18.9 529.4c1.1 2.2 1.7 4.6 1.7 7.1 0 2.4-0.6 4.8-1.7 6.9l36.9 0c17.1 0 11.1 14.8 13.5 34.9 7.3 27.3 35.9 38.1 62.6 41.7-1.5-2.4-4.3-7.9-4.3-10.9 0-3.1 0.9-5.7 2.7-8.3-23.3-1.1-29.9-7.3-39.3-22.3-4.8-11.4 5.7-49.2-28.7-49.2z"  
  style=" stroke:#4B0082; stroke-width:3; fill:#ded9d5; stroke-dasharray:571; stroke-dashoffset:571;">
  <animate id="dash" attributeName="stroke-dashoffset" values="571;0;571" begin="path1.mouseover" restart="whenNotActive" dur="5s" fill="freeze" repeatCount="1"></animate>
  </path>
</svg>     

begin="path1.mouseover" - 启动动画的命令,其中path1 是路径标识符

restart="whenNotActive" - 防止重新动画

values="571;0;571" - 从 571px 到零并返回的路径上的动画

如果我正确理解了问题的作者,动画不是路径线需要的,而是用颜色填充path 形成的整个图形。

当路径没有关闭时,这样做很容易——将线条的粗细增加到所需的值并使用动画stroke-dashoffset

为了解决这些矛盾,您可以使用这种技术:在矢量编辑器中打开我们的代码,并在图形中间绘制一条额外的曲线。

并且这条线将被动画化。要开始动画,请移动光标。

<svg id="svg2" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"   viewBox="-50 550 372 80.4"  version="1.1">
  <path d="m18.9 529.4c1.1 2.2 1.7 4.6 1.7 7.1 0 2.4-0.6 4.8-1.7 6.9l36.9 0c17.1 0 11.1 14.8 13.5 34.9 7.3 27.3 35.9 38.1 62.6 41.7-1.5-2.4-4.3-7.9-4.3-10.9 0-3.1 0.9-5.7 2.7-8.3-23.3-1.1-29.9-7.3-39.3-22.3-4.8-11.4 5.7-49.2-28.7-49.2z"  
  style="fill:#F8F3EF;stroke-width:1; stroke:none;" />
     
  <path style="stroke-dasharray:152;stroke-dashoffset:152; fill:none;stroke-width:2;stroke:yellowgreen;"
  d="m20.8 535.9c24.9 2.5 55.9-6.4 57.2 15.4 3.5 19.3-1.6 31.7 14 45.2 21.1 17.5 35.4 13 35.4 13">
  <animate id="dash" attributeName="stroke-dashoffset" values="152;0" begin="svg2.mouseover" restart="whenNotActive" dur="3s"    fill="freeze" repeatCount="1">
  </animate>

	</path>
</svg>   

接下来,增加线条的粗细——stroke-width: 20;,得到想要的结果:

<svg id="svg2" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"   viewBox="-50 550 372 80.4"  version="1.1">
    
  <path d="m18.9 529.4c1.1 2.2 1.7 4.6 1.7 7.1 0 2.4-0.6 4.8-1.7 6.9l36.9 0c17.1 0 11.1 14.8 13.5 34.9 7.3 27.3 35.9 38.1 62.6 41.7-1.5-2.4-4.3-7.9-4.3-10.9 0-3.1 0.9-5.7 2.7-8.3-23.3-1.1-29.9-7.3-39.3-22.3-4.8-11.4 5.7-49.2-28.7-49.2z"  
  style="fill:#F8F3EF;stroke-width:1; stroke:none;" />
  
    
  <path style="stroke-dasharray:152;stroke-dashoffset:152; fill:none;stroke-width:20;stroke:yellowgreen;"
  d="m20.8 535.9c24.9 2.5 55.9-6.4 57.2 15.4 3.5 19.3-1.6 31.7 14 45.2 21.1 17.5 35.4 13 35.4 13">
  <animate id="dash" attributeName="stroke-dashoffset" values="152;0" begin="svg2.mouseover" restart="whenNotActive" dur="3s"    fill="freeze" repeatCount="1">
  </animate>

	</path>
</svg>   

使用filter的解决方案

提出解决方案的想法 - SVG Filter tag on hover @Holger Will

填充路径的动画是通过改变滤镜dx的属性来实现的——沿X轴偏移。

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
   viewBox="-50 540 372 80.4">
   <defs>
    <filter id="violet-fill" x="0%" y="0%">
      <feFlood flood-color="#F8F3EF" />
      <feOffset dx="0">
        <animate id="anim" attributeName="dx" values="0;115;0" dur="5s" begin="path1.mouseover" restart="whenNotActive" fill="freeze"/> 
      </feOffset>
      <feComposite operator="in" in2="SourceGraphic" />
      <feComposite operator="over" in2="SourceGraphic" />
    </filter>
  </defs>
  <style>
  path 
  filter: url(#violet-fill);

  </style>
  <path id="path1" d="m18.9 529.4c1.1 2.2 1.7 4.6 1.7 7.1 0 2.4-0.6 4.8-1.7 6.9l36.9 0c17.1 0 11.1 14.8 13.5 34.9 7.3 27.3 35.9 38.1 62.6 41.7-1.5-2.4-4.3-7.9-4.3-10.9 0-3.1 0.9-5.7 2.7-8.3-23.3-1.1-29.9-7.3-39.3-22.3-4.8-11.4 5.7-49.2-28.7-49.2z"  
  style=" stroke:#4B0082; fill:#F8F3EF;"/>
</svg>

第二个借助动画的解决方案filter

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
   viewBox="-50 540 372 80.4">
   <defs>
    <filter id="violet-fill" x="0%" y="0%">
      <feFlood flood-color="#ded9d5" />
      <feOffset dx="0">
        <animate id="anim" attributeName="dx" values="0;115;0" dur="5s" begin="path1.mouseover" restart="whenNotActive" fill="freeze"/> 
      </feOffset>
      <feComposite operator="in" in2="SourceGraphic" />
      <feComposite operator="over" in2="SourceGraphic" />
    </filter>
  </defs>
  <style>
  path 
  filter: url(#violet-fill);

  </style>
  <path id="path1" d="m18.9 529.4c1.1 2.2 1.7 4.6 1.7 7.1 0 2.4-0.6 4.8-1.7 6.9l36.9 0c17.1 0 11.1 14.8 13.5 34.9 7.3 27.3 35.9 38.1 62.6 41.7-1.5-2.4-4.3-7.9-4.3-10.9 0-3.1 0.9-5.7 2.7-8.3-23.3-1.1-29.9-7.3-39.3-22.3-4.8-11.4 5.7-49.2-28.7-49.2z"  
  style=" stroke-width:1; stroke:violet;   fill:#4B0082;"/>
</svg>  

【讨论】:

【参考方案2】:

我会添加一个类而不是一个 ID,并在该类上使用 CSS ":hover"。

或者你可以两者兼得。

这是交互式 svg 的绝佳页面。 Mouseover effects in SVGs

示例代码,必须删除 svg 中的硬编码样式才能使 css 生效。

.effective
fill:red;


.effective:hover
fill:black;
 transition: fill 2s ease-in;
<svg   viewBox="0 0 744.09449 159.44881">
<path  d="m 18.929688,529.44141 c 1.140051,2.17164 1.739409,4.60197 1.74414,7.07226 -0.0033,2.41521 -0.575072,4.79339 -1.666016,6.92969 l 36.876954,0 c 17.101683,0 11.124297,14.78094 13.525192,34.92207 7.304679,27.32129 35.935342,38.13518 62.612922,41.73111 -1.5457,-2.42739 -4.33484,-7.94712 -4.33733,-10.8524 0.005,-3.11453 0.90166,-5.74434 2.66254,-8.27277 -23.30774,-1.1068 -29.8766,-7.34118 -39.33413,-22.29658 -4.829034,-11.35821 5.68082,-49.23338 -28.703413,-49.23338 z" transform="translate(0.5714286,1.42857)" class="effective" />
</svg>

【讨论】:

我打不开这个链接你能不能给我一些其他的 这是您想要的过渡吗? 我希望颜色像管道中的水一样流动 如果你想让它跟随管道,我会使用一种算法来获取点和一个起点,它使用空间填充树跟随管道,而不是随机流动不透明的圆圈直到它填满并将其与我最后使用的过渡相结合。您是否要为水管设置动画?我唯一能想到的另一件事是,您可以使用剪贴蒙版,但它看起来不像水,只是有点。 你能给我一份样本吗

以上是关于需要为曲线填充 Svg 动画的主要内容,如果未能解决你的问题,请参考以下文章

使用填充为 svg 设置动画

需要帮助清理 SVG 动画

SVG波浪动画

如何用svg在网页中画一条带箭头的连接线

如何在 mouseover/mouseout (SMIL) 上为内联 SVG 的填充属性设置动画

给定路径的 Svg 填充动画