如何向SVG路径添加动态渐变?

13
我有一个心形SVG路径,如下所示:

<svg viewBox="0 0 100 100">
<path className="" d="M20,31 C15.4189994,27.2225585 12.5023327,24.2225585 11.25,22 C10.2743515,20.6156479 10,19.6181623 10,18.1428571 C10,15.5113854 12.4883456,13 15,13 C17.3176009,13 18.9621484,13.8491346 20,15.5714286 C21.0382977,13.8491346 22.6828452,13 25,13 C27.5116544,13 30,15.5113854 30,18.1428571 C30,19.6181623 29.7256485,20.6156479 28.75,22 C27.497816,24.2225585 24.5811493,27.2225585 20,31 Z" />
</svg>

我想为它添加渐变效果并使渐变从左到右移动,就像这颗心在闪烁。

然而,path 不接受 background 属性,如果我使用 fill,也不能将渐变设置为值。它也没有 background-position 属性(因此我无法使用 @keyframes 将背景位置从左到右移动)。

有什么方法可以实现这一点吗?


只是一个想法:https://jsfiddle.net/qraskdyg/1/ - sol
这可能会有所帮助 https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/clipPath - Carol McKay
1个回答

16
你可以使用SVG的SMIL动画。其想法是通过动画渐变的颜色停止或偏移来创建所需的效果:

你可以使用SVG的SMIL动画。其想法是通过动画颜色渐变的停止点或偏移来创建所需的效果:

svg {
 border:1px solid;
 width:200px;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
   viewBox="10 10 24 24">
    <defs>
        <linearGradient id="linear-gradient" x1="-100%" y1="0" x2="200%" y2="0" >
            <stop offset="0" stop-color="red">
               <animate attributeName="offset" values="0;0.2;0.5" dur="2s" repeatCount="indefinite"  /> 
            </stop>
            <stop offset="0.5" stop-color="yellow">
                <animate attributeName="offset" values="0.5;0.7;0.8;1" dur="2s" repeatCount="indefinite"  /> 
            </stop>
        </linearGradient>
    </defs>
<path fill="url(#linear-gradient)" d="M20,31 C15.4189994,27.2225585 12.5023327,24.2225585 11.25,22 C10.2743515,20.6156479 10,19.6181623 10,18.1428571 C10,15.5113854 12.4883456,13 15,13 C17.3176009,13 18.9621484,13.8491346 20,15.5714286 C21.0382977,13.8491346 22.6828452,13 25,13 C27.5116544,13 30,15.5113854 30,18.1428571 C30,19.6181623 29.7256485,20.6156479 28.75,22 C27.497816,24.2225585 24.5811493,27.2225585 20,31 Z" />
</svg>

颜色动画效果:

svg {
 border:1px solid;
 width:200px;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
   viewBox="10 10 24 24">
    <defs>
        <linearGradient id="linear-gradient" x1="0" y1="0" x2="100%" y2="0" >
            <stop offset="0" stop-color="red">
               <animate attributeName="stop-color" values="yellow;red" dur="2s" repeatCount="indefinite"  /> 
            </stop>
            <stop offset="1" stop-color="yellow">
                <animate attributeName="stop-color" values="red;yellow" dur="2s" repeatCount="indefinite"  /> 
            </stop>
        </linearGradient>
    </defs>
<path fill="url(#linear-gradient)" d="M20,31 C15.4189994,27.2225585 12.5023327,24.2225585 11.25,22 C10.2743515,20.6156479 10,19.6181623 10,18.1428571 C10,15.5113854 12.4883456,13 15,13 C17.3176009,13 18.9621484,13.8491346 20,15.5714286 C21.0382977,13.8491346 22.6828452,13 25,13 C27.5116544,13 30,15.5113854 30,18.1428571 C30,19.6181623 29.7256485,20.6156479 28.75,22 C27.497816,24.2225585 24.5811493,27.2225585 20,31 Z" />
</svg>

另一个想法是考虑在蒙版内部的路径,然后运行CSS动画以轻松地动画化背景属性:

另一个思路是将路径限制在一个遮罩层内,然后使用CSS动画轻松地实现背景属性动画:

svg {
  border: 1px solid;
  width: 200px;
}

.box {
  width:200px;
  height:200px;
  background:linear-gradient(to right,red,green,blue) left/200% 100%;
  -webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"  viewBox="10 10 24 24"><path  d="M20,31 C15.4189994,27.2225585 12.5023327,24.2225585 11.25,22 C10.2743515,20.6156479 10,19.6181623 10,18.1428571 C10,15.5113854 12.4883456,13 15,13 C17.3176009,13 18.9621484,13.8491346 20,15.5714286 C21.0382977,13.8491346 22.6828452,13 25,13 C27.5116544,13 30,15.5113854 30,18.1428571 C30,19.6181623 29.7256485,20.6156479 28.75,22 C27.497816,24.2225585 24.5811493,27.2225585 20,31 Z" /></svg>') center/contain;
          mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"  viewBox="10 10 24 24"><path  d="M20,31 C15.4189994,27.2225585 12.5023327,24.2225585 11.25,22 C10.2743515,20.6156479 10,19.6181623 10,18.1428571 C10,15.5113854 12.4883456,13 15,13 C17.3176009,13 18.9621484,13.8491346 20,15.5714286 C21.0382977,13.8491346 22.6828452,13 25,13 C27.5116544,13 30,15.5113854 30,18.1428571 C30,19.6181623 29.7256485,20.6156479 28.75,22 C27.497816,24.2225585 24.5811493,27.2225585 20,31 Z" /></svg>') center/contain;
          
   animation:change 2s infinite linear alternate;
}
@keyframes change {
  to {
    background-position:right;
  }
}
<div class="box">
</div>

获取更多背景计算细节的相关问题:在线性渐变中使用百分比值进行背景定位


实用技巧 - 使用fakeSMIL js库使其兼容IE/Edge。 - Michael Mullany
1
不循环。总是在结束和重新开始之间跳跃。 - aviya.developer
@aviya.developer 这个程序并不是为了循环而设计的。跳跃是有意设计的。我只是展示使用SVG的不同技巧。 - Temani Afif
@TemaniAfif 你通常用什么来制作短动画?比如预加载等等?我尝试过SVG,但到目前为止它并不是很方便。 - aviya.developer
@aviya.developer 这取决于您想要实现的动画。没有通用解决方案。 - Temani Afif

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