How to add animated gradient to an svg path?

前端 未结 1 1120
[愿得一人]
[愿得一人] 2020-12-09 20:09

I have a heart svg path like so:




        
相关标签:
1条回答
  • 2020-12-09 20:34

    You can use the SMIL animation of SVG. The idea is to animate the color-stop or the offset of the gradient to create the needed effect:

    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>

    Animating the color:

    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>


    Another idea is to consider the path inside a mask then you run a CSS animation to easily animate the background properties:

    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>

    Related question to get more detail about background calculation: Using percentage values with background-position on a linear-gradient

    0 讨论(0)
提交回复
热议问题