Reputation: 43
I have a very simple path within a SVG.
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61 57"
version="1.1" x="0px" y="0px">
<defs>
<style type="text/css"><![CDATA[
]]>
</style>
</defs>
<path id="pipe" d="
M8.0178,52.0035
L27.0178,52.0035
C42.4568,52.0035 55.0178,39.4425 55.0178,24.0035
L55.0178,8.0035
L43.0178,8.0035
L43.0178,24.0035
C43.0178,32.8255 35.8398,40.0035 27.0178,40.0035
L8.0178,40.0035
L8.0178,52.0035
Z">
</path>
</svg>
(Preview: https://i.sstatic.net/FfBRg.png)
What I'd like to achive is that I have 3 separate gradients or filling spaces:
Alternatively I could also use a single gradient with multiple stop colors.
The following image illustrates the wanted result: https://i.sstatic.net/I4CNa.png In this case the rectangles I added illustrate the gradient that I want to use along the whole curve.
I did some research regarding advanced gradients in SVG but I was not able to understand how to apply them or if that is even necessary. I understand how to apply radial and linear gradients to rectangles or even to curves but that did not deliver the expected result.
I also found Can I apply a gradient along an SVG path? which creates a gradient in the tube from left to right (so to say) and I'd like it from top to bottom.
Do you guys have any ideas how to solve this?
Upvotes: 3
Views: 5642
Reputation: 13017
You can may get the result you want by using filter
s with blur or lighting. Here is a good article on advanced filters: https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 150 150" >
<defs>
<filter id="filter1">
<feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blurOut" />
<!-- We cut off the parts that overlap the source graphic… -->
<feComposite operator="in" in="blurOut" in2="SourceAlpha" result="COMPOSITE"/>
<!-- … and then merge source graphic and lighting effect: -->
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode in="COMPOSITE"/>
</feMerge>
</filter>
<!-- https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/ -->
<filter id="filter2">
<!--We create a heightmap by blurring the source: -->
<feGaussianBlur stdDeviation="5" in="SourceAlpha" result="BLUR"/>
<!-- We then define a lighting effect with a point light that is positioned at virtual 3D coordinates x: 40px, y: -30px, z: 200px: -->
<feSpecularLighting surfaceScale="6" specularConstant="1" specularExponent="30" lighting-color="#white" in="BLUR" result="SPECULAR">
<fePointLight x="40" y="40" z="2000" />
</feSpecularLighting>
<!-- We cut off the parts that overlap the source graphic… -->
<feComposite operator="in" in="SPECULAR" in2="SourceAlpha" result="COMPOSITE"/>
<!-- … and then merge source graphic and lighting effect: -->
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode in="COMPOSITE"/>
</feMerge>
</filter>
</defs>
<path stroke="white" stroke-width="20" fill="none" filter="url(#filter1)"
d="M-90,50 h150 a20,20 0 0,0 20,-20 v-150" />
<path stroke="black" stroke-width="20" fill="none" filter="url(#filter2)"
d="M-40,100 h150 a20,20 0 0,0 20,-20 v-150" />
</svg>
Upvotes: 7
Reputation: 101820
In general it is not possible to create gradients that flow along a path.
However, in cases like yours which only involve straight pieces and circular arcs, you can achieve the effect by breaking the shape up into those sections. Then you apply a different gradient to each part. You use a <linearGradient>
for the straight sections, and a <radialGredient>
for the curved sections.
In the example below, I have used a very simplified gradient for the "pipe" effect. You will probably wish to add more stops to yours to give a better 3D effect.
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61 57"
version="1.1" x="0px" y="0px">
<defs>
<linearGradient id="horizontalPipe" x2="0" y2="1">
<stop offset="0" stop-color="white"/>
<stop offset="0.25" stop-color="black"/>
<stop offset="0.75" stop-color="black"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<linearGradient id="verticalPipe">
<stop offset="0" stop-color="white"/>
<stop offset="0.25" stop-color="black"/>
<stop offset="0.75" stop-color="black"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<radialGradient id="curvedPipe" cx="0" cy="0" r="1">
<stop offset="0.57" stop-color="white"/>
<stop offset="0.677" stop-color="black"/>
<stop offset="0.893" stop-color="black"/>
<stop offset="1" stop-color="white"/>
</radialGradient>
</defs>
<rect x="8" y="40" width="19" height="12" fill="url(#horizontalPipe)"/>
<path d="M 27,40 A 16,16, 0,0,0 43,24 H 55 A 28,28, 0,0,1, 27,52 Z" fill="url(#curvedPipe)"/>
<rect x="43" y="8" width="12" height="16" fill="url(#verticalPipe)"/>
</svg>
Upvotes: 3