Optiq
Optiq

Reputation: 3182

I need help minimizing instances of SVG gradients

I have a logo I created in Illustrator that I'm manually crafting into an SVG file piece by piece. It's a highly detailed illustration with lots of layering and blending so I have a lot of repeated gradients that only differ in the values of the gradientTransform property.

Here's an example

<radialGradient id="sil_bor_clr_layer_01" cx="145.8111" cy="91.9766" r="5.5753" gradientTransform="matrix(1.665142e-02 -0.9999 1.0812 1.800584e-02 43.939 236.1114)" gradientUnits="userSpaceOnUse">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.6007" style="stop-color:#DBE2E8"/>
    <stop  offset="1" style="stop-color:#C0CDD8"/>
</radialGradient>

<radialGradient id="sil_bor_clr_layer_02" cx="121.087" cy="94.1915" r="6.7356" gradientTransform="matrix(-0.1704 -0.9854 0.917 -0.1586 55.3406 228.4433)" gradientUnits="userSpaceOnUse">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.6007" style="stop-color:#DBE2E8"/>
    <stop  offset="1" style="stop-color:#C0CDD8"/>
</radialGradient>

<radialGradient id="sil_bor_clr_layer_03" cx="98.1764" cy="102.6783" r="7.6206" gradientTransform="matrix(-0.5989 -0.8008 0.6381 -0.4771 91.458 230.294)" gradientUnits="userSpaceOnUse">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.6007" style="stop-color:#DBE2E8"/>
    <stop  offset="1" style="stop-color:#C0CDD8"/>
</radialGradient>

I have another 21 elements that use this same gradient which means I'll have to define it 21 more times just for the sake of defining the gradientTransform property.

Is there a way for me to define the gradientTransform on the SVG elements using the gradient so I can just define them once? These particular elements have a color layer, shadow layer and highlight layer which will be about 60+ instances of the same thing which is pretty ridiculous. I'm currently doing this in Angular so I know I could make components and export a few const to take care of this, but I'd prefer to keep it svg and css if possible.

Upvotes: 0

Views: 55

Answers (1)

Robert Longson
Robert Longson

Reputation: 124089

You can use the href property to reference a template gradient.

If you want to support Safari you'll need to use xlink:href as Safari doesn't yet support bare href.

head, body, svg {
  width: 100%;
  height: 100%;
}
<svg viewBox="0 0 400 400">
  <defs>
    <radialGradient id="template">
      <stop offset="10%" stop-color="gold"/>
      <stop offset="95%" stop-color="green"/>
    </radialGradient>
    <radialGradient id="gradient1" gradientTransform="translate(0.25, 0.25) scale(0.5)" href="#template"/>
  </defs>

  <circle fill="url(#template)" cx="60" cy="60" r="50"/>
  <circle fill="url(#gradient1)" cx="160" cy="60" r="50"/>
</svg>

If your gradient is supposed to look the same on each shape though, you'd be better off having one gradient and using objectBoundingBox units instead of userSpaceOnUse units.

Upvotes: 3

Related Questions