svgsvg-animate

Why doesn't animate inside a linearGradient referenced by another linearGradient work?


Sample SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140">
<linearGradient id="reuseme" gradientUnits="userSpaceOnUse" spreadMethod="reflect">
    <stop offset="0" stop-color="red"/>
    <stop offset="1" stop-color="black"/>
    <animate attributeName="y1" dur="2s" repeatCount="indefinite" values="0%;150%;0%"/>
</linearGradient>
<linearGradient id="a" x1="22.677" x2="132.625" y1="338.835" y2="338.835" href="#reuseme"/>
<rect fill="url(#a)" x="10" y="10" width="130" height="130"/>
</svg>
 

Why can't I use <animate> within my reusable <linearGradient id="reuseme"> above? When I try, the animation does not play. If I move the <animate> tag to the bottom <linearGradient id="a"> it works:

<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140">
<linearGradient id="reuseme" gradientUnits="userSpaceOnUse" spreadMethod="reflect">
    <stop offset="0" stop-color="red"/>
    <stop offset="1" stop-color="black"/>
</linearGradient>
<linearGradient id="a" x1="22.677" x2="132.625" y1="338.835" y2="338.835" href="#reuseme">
    <animate attributeName="y1" dur="2s" repeatCount="indefinite" values="0%;150%;0%"/>
</linearGradient>
<rect fill="url(#a)" x="10" y="10" width="130" height="130"/>
</svg>
 

The reason I want to do this is because I have lots of shapes that use the same gradient and the same animation. It stands to reason if I can reuse a gradient, I should be able to reuse its animation too. I have also tried <use> and <animate href="#foo"> to try to achieve the same thing but failed miserably.


Solution

  • Because you're setting y1 in the gradient with id="a" and that overrides any setting in id="reuseme".

    Any properties/attributes/stops are used from the first gradient that's encountered with that property/attribute or stops in the reference chain.

    I've removed y1 from id="a" below so the other gradient now animated because its y1 is not overridden any more.

    <svg xmlns="http://www.w3.org/2000/svg" width="140" height="140">
    <linearGradient id="reuseme" gradientUnits="userSpaceOnUse" spreadMethod="reflect">
        <stop offset="0" stop-color="red"/>
        <stop offset="1" stop-color="black"/>
        <animate attributeName="y1" dur="2s" repeatCount="indefinite" values="0%;150%;0%"/>
    </linearGradient>
    <linearGradient id="a" x1="22.677" x2="132.625" y2="338.835" href="#reuseme">
        <!-- moving <animate/> here does work -->
    </linearGradient>
    <rect fill="url(#a)" x="10" y="10" width="130" height="130"/>
    </svg>