Eliya Cohen
Eliya Cohen

Reputation: 11468

Transition stroke color to stroke gradient

I have the following svg:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800">
  <defs>
    <style>.cls-1{fill:url(#linear-gradient);}</style>
    <linearGradient id="linear-gradient" x1="-28.83" y1="770.92" x2="771.05" y2="-28.95" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#e91e63"/>
      <stop offset="0.18" stop-color="#ea2763"/>
      <stop offset="0.49" stop-color="#ee4163"/>
      <stop offset="0.88" stop-color="#f46a63"/>
      <stop offset="0.99" stop-color="#f67863"/>
    </linearGradient>
  </defs>
  <title>Asset 5</title>
  <g id="Layer_2" data-name="Layer 2">
    <g id="Layer_5" data-name="Layer 5">
      <path class="cls-1"
            d="M602.54,800H.25L365.34,458.18,170.54,170.85h458.1v115H387.44L468.91,406a97.51,97.51,0,0,1-14.06,125.9L291.34,685h311.2A82.58,82.58,0,0,0,685,602.48V115H115V583.93H0V0H800V602.48C800,711.39,711.42,800,602.54,800Z"/>
    </g>
  </g>
</svg>

As you can see, this is an SVG with <path> that has a stroke with this gradient:

<linearGradient id="linear-gradient" x1="-28.8" y1="770.96" x2="771.08" y2="-28.92" gradientUnits="userSpaceOnUse">
  <stop offset="0" stop-color="#e91e63"></stop>
  <stop offset="0.18" stop-color="#ea2763"></stop>
  <stop offset="0.49" stop-color="#ee4163"></stop>
  <stop offset="0.88" stop-color="#f46a63"></stop>
  <stop offset="0.99" stop-color="#f67863"></stop>
</linearGradient>

So far so good. Now, I want to first show it has a white svg, and then animate the color to gradient. So I tried to do:

@keyframes drawLogo {
    from { stroke: url(#linear-gradient-white) }
    to { stroke: url(#linear-gradient); }
}

but the gradient appeared instantly. I want it to appear with ease.

Upvotes: 1

Views: 2730

Answers (1)

enxaneta
enxaneta

Reputation: 33044

As Robert Longson commented you may try to use SMIL animations to animate the stop-color like so:

.cls-1{fill:url(#linear-gradient);
 }
<svg width="200" viewBox="0 0 800 800">
  <defs>
    
    <linearGradient id="linear-gradient" x1="-28.83" y1="770.92" x2="771.05" y2="-28.95" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#fff">
        <animate attributeName="stop-color"
       attributeType="XML"
       values="#fff;#e91e63;#fff"
       dur="5s"
       repeatCount="indefinite"/>
      </stop>
      <stop offset="0.99" stop-color="#fff">
        <animate attributeName="stop-color"
       attributeType="XML"
       values="#fff;#f67863;#fff"
       dur="5s"
       repeatCount="indefinite"/>
      </stop>
    </linearGradient>
    
   
  </defs>
  <title>Asset 5</title>
  <g id="Layer_2" data-name="Layer 2">
    <g id="Layer_5" data-name="Layer 5">
      <path class="cls-1"
            d="M602.54,800H.25L365.34,458.18,170.54,170.85h458.1v115H387.44L468.91,406a97.51,97.51,0,0,1-14.06,125.9L291.34,685h311.2A82.58,82.58,0,0,0,685,602.48V115H115V583.93H0V0H800V602.48C800,711.39,711.42,800,602.54,800Z"/>
    </g>
  </g>
</svg>

Also you need to fill not to stroke

UPDATE

the OP is asking:

Can you explain why should I have to use fill instead of stroke

It's because you have a closed path that is using a fill to start with.

In order to use a stroke you have to either draw the path as a stroke for example like this:

<svg width="200" viewBox="0 0 800 800">
  <defs>
<linearGradient id="linear-gradient" x1="-28.83" y1="770.92" x2="771.05" y2="-28.95" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#e91e63"/>
      <stop offset="0.18" stop-color="#ea2763"/>
      <stop offset="0.49" stop-color="#ee4163"/>
      <stop offset="0.88" stop-color="#f46a63"/>
      <stop offset="0.99" stop-color="#f67863"/>
    </linearGradient>
</defs>
    <path id="theStroke" stroke="url(#linear-gradient)" fill="none"  stroke-width="130" d="M55,600V55H755V500C755,700 700,725 600,725 H155L420,475Q455,455 400,375L300 250H635" />
</svg>

I did it manually and it's not perfect. However you can use the path you have to mask the stroke like so:

<svg width="200" viewBox="0 0 800 800">
  <defs>
<linearGradient id="linear-gradient" x1="-28.83" y1="770.92" x2="771.05" y2="-28.95" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#e91e63"/>
      <stop offset="0.18" stop-color="#ea2763"/>
      <stop offset="0.49" stop-color="#ee4163"/>
      <stop offset="0.88" stop-color="#f46a63"/>
      <stop offset="0.99" stop-color="#f67863"/>
    </linearGradient>
    <mask id="m">
       <path fill="white" d="M602.54,800H.25L365.34,458.18,170.54,170.85h458.1v115H387.44L468.91,406a97.51,97.51,0,0,1-14.06,125.9L291.34,685h311.2A82.58,82.58,0,0,0,685,602.48V115H115V583.93H0V0H800V602.48C800,711.39,711.42,800,602.54,800Z"/>
    </mask>

  </defs>

  <path id="theStroke" stroke="url(#linear-gradient)" fill="none"  stroke-width="160" d="M55,600V55H755V500C755,700 700,725 600,725 H155L420,475Q455,455 400,375L300 250H635" style="mask: url(#m)"/>
</svg>

Now if you want you may try to animate the stroke, however the path has sharp angles and the animation won't happen as you want:

#theStroke{
stroke-dasharray:3428; 
stroke-dashoffset:3428;
animation: dash 5s linear alternate infinite;
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}
<svg width="200" viewBox="0 0 800 800">
  <defs>
<linearGradient id="linear-gradient" x1="-28.83" y1="770.92" x2="771.05" y2="-28.95" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#e91e63"/>
      <stop offset="0.18" stop-color="#ea2763"/>
      <stop offset="0.49" stop-color="#ee4163"/>
      <stop offset="0.88" stop-color="#f46a63"/>
      <stop offset="0.99" stop-color="#f67863"/>
    </linearGradient>
    <mask id="m">
       <path fill="white" d="M602.54,800H.25L365.34,458.18,170.54,170.85h458.1v115H387.44L468.91,406a97.51,97.51,0,0,1-14.06,125.9L291.34,685h311.2A82.58,82.58,0,0,0,685,602.48V115H115V583.93H0V0H800V602.48C800,711.39,711.42,800,602.54,800Z"/>
    </mask>
 
  </defs>

  <path id="theStroke" stroke="url(#linear-gradient)" fill="none"  stroke-width="160" 
            d="M55,600V55H755V500C755,700 700,725 600,725 H155L420,475Q455,455 400,375L300 250H635" style="mask: url(#m)"/>
</svg>

Upvotes: 2

Related Questions