3
votes

I am creating in Javascript different L- shaped paths. They differ in length and in position. I would like to have a linearGradient as a stroke for them, where the first stop offset is at the position of x=10 pixels, i.e. the change in color always starts after x pixels.

Using gradient the standard way just offers relative positioning (e.g. wrt the object bounding box). This results in different stop offsets due to the different object bounding boxes.

Here is one example how it looks like:

  path.p1 {
    fill: none;
    stroke-width: 20px;
  }
<svg height="600" width="1000">


  <path class="p1" d="M10 10 V 100 H 100 " stroke="url(#cl1)"/>
  <path class="p1" d="M150 10 V 100 H 200 " stroke="url(#cl1)"/>
  <path class="p1" d="M250 10 V 100 H 400 " stroke="url(#cl1)"/>

    <defs>
        <linearGradient id="cl1" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0" style="stop-color:grey;stop-opacity:1" />
            <stop offset="0.02" style="stop-color:grey;stop-opacity:1" />
            <stop offset="0.15" style="stop-color:orange;stop-opacity:1" />
            <stop offset="0.2" style="stop-color:orange;stop-opacity:1" />
        </linearGradient>
    </defs>
  
</svg>

Is there a way to use one gradient but a clever way to reference it through SVG nesting or javascript?

1

1 Answers

5
votes

Use gradientUnits="userSpaceOnUse". This way, the gradient is positioned in absolute units, but always in the local coordinate system of the element it is defined on.

In your case, having all paths in the same coordinate system would mean you defined an overall gradient spanning all paths. To avoid that, you have to change that, for example by defining a transform attribute. Each consecutive path is moved more to the right, while its starting point, measured in the local coordinate system, remains in the same place.

  path.p1 {
    fill: none;
    stroke-width: 20px;
  }
<svg height="600" width="1000">


  <path class="p1" d="M10 10 V 100 H 100 " stroke="url(#cl1)"/>
  <path class="p1" d="M10 10 V 100 H 60 " stroke="url(#cl1)" transform="translate(140)"/>
  <path class="p1" d="M10 10 V 100 H 160 " stroke="url(#cl1)" transform="translate(240)"/>

    <defs>
        <linearGradient id="cl1" gradientUnits="userSpaceOnUse" x1="10" y1="0" x2="110" y2="0">
            <stop offset="0" style="stop-color:grey;stop-opacity:1" />
            <stop offset="0.02" style="stop-color:grey;stop-opacity:1" />
            <stop offset="0.15" style="stop-color:orange;stop-opacity:1" />
            <stop offset="0.2" style="stop-color:orange;stop-opacity:1" />
        </linearGradient>
    </defs>
  
</svg>