linear gradient in Svelte each loop not working

36 Views Asked by At

I have created a linearGradient for an SVG chord diagram using Svelte. Each chord should have its own gradient assigned from among 7 colors, for a total of 21 separate gradients assigned to 21 paths. Inspecting the SVG element, I can see the Svelte #each loop correctly assigns the color stops inside the linearGradient. However, the paths are not getting the updated linearGradient information. I have tried approaches including using index to update the reference each time, but none seem to work. I have tried my best to phrase this question correctly according to Stackoverflow. Any thoughts are much appreciated!

    {#each ribbons as ribbon, i}
<!-- ribbons with linear gradients -->
<defs>
  <linearGradient id={"gradient"} gradientTransform="rotate(90)">
    <stop offset="5%" stop-color={`${colors[ribbon.source.index]}`} />
    <stop offset="95%" stop-color={`${colors[ribbon.target.index]}`} />
  </linearGradient>
</defs>
<path
  d={ribbon.path}
  fill={"url('#gradient')"}
  fill-opacity={0.7}
>
</path>

{/each}

1

There are 1 best solutions below

3
Stephane Vanraes On

Likely they are all using the same gradient because you are effectively rendering this

<defs>
  <linearGradient id="gradient">...</linearGradient>
</defs>
<path fill="url(#gradient)">...</path>
<defs>
  <linearGradient id="gradient">...</linearGradient>
</defs>
<path fill="url('#gradient')">...</path>

Note that all gradients use the same id and all paths point to the same id as well. Since ids are supposed to be unique the browser will simply ignore the second definition when looking up the id in url(#gradient).

You can solve this by making the ids unique, maybe use the index or other unique identifier like the actual chord?

<linearGradient="gradient-{i}">
<path fill="url('#gradient-{i}')">