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?
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>
I have used two path in my svg group element for a line and circle and applied same gradient color for both circle and line path.
Here is my SVG code.
<svg id="legend_scrollcontent_svg" class="e-designerhide" style="height: 37px; width: 75px;">
<g id="scrollcontent_svg_Legend">
<defs>
<linearGradient id="scrollcontent_svg_legend0Gradient" x1="0%" y1="0%" x2="0%" y2="558%">
<stop offset="0%" stop-color="#F34649" stop-opacity="1">
<stop offset="100%" stop-color="#B74143" stop-opacity="1">
</linearGradient>
</defs>
<g id="scrollcontent_svg_Legend0" cursor="pointer">
<path id="scrollcontent_svg_LegendItemShape0" fill="url(#scrollcontent_svg_legend0Gradient)" stroke-width="2" stroke="url(#scrollcontent_svg_legend0Gradient)" opacity="1" d="M 7.5 19.5 L 12 19.5 M 18 19.5 L 22.5 19.5" lgndctx="true">
<path id="scrollcontent_svg_LegendItemShape1" fill="transparent" stroke-width="2" stroke="url(#scrollcontent_svg_legend0Gradient)" opacity="1" d="M 12 19.5 a 3 3 0 1 0 6 0 a 3 3 0 1 0 -6 0" lgndctx="true">
</g>
</g>
</svg>
In the first link i have added two path in the group and applied gradient color.. But the gradient color is not applied.
In the second link, i have removed line path and now it is applying gradient color to circle path
Anyone can help me on resolving this issue.
Thanks,
Bharathi.
You've two problems.
you're not closing your elements. SVG elements are not self closing like html ones are they need to end /> and not >
objectBoundingBox gradients require shapes not to be entirely horizontal or vertical. You're going to need to make the gradient userSpaceOnUse in order for it to apply to the horizontal line.
Something like this
<svg id="legend_scrollcontent_svg" class="e-designerhide" style="height: 200px; width: 200px;" viewBox="5 5 20 20">
<g id="scrollcontent_svg_Legend">
<defs>
<linearGradient id="scrollcontent_svg_legend0Gradient" x1="0%" y1="0%" x2="0%" y2="558%" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#F34649" stop-opacity="1"/>
<stop offset="100%" stop-color="#B74143" stop-opacity="1"/>
</linearGradient>
</defs>
<g id="scrollcontent_svg_Legend0" cursor="pointer">
<path id="scrollcontent_svg_LegendItemShape0" fill="url(#scrollcontent_svg_legend0Gradient)" stroke-width="2" stroke="url(#scrollcontent_svg_legend0Gradient)" opacity="1" d="M 7.5 19.5 L 12 19.5 M 18 19.5 L 22.5 19.5" lgndctx="true"/>
<path id="scrollcontent_svg_LegendItemShape1" fill="transparent" stroke-width="2" stroke="url(#scrollcontent_svg_legend0Gradient)" opacity="1" d="M 12 19.5 a 3 3 0 1 0 6 0 a 3 3 0 1 0 -6 0" lgndctx="true"/>
</g>
</g>
</svg>
You may need to adjust the y1 and y2 values to get the gradient you want. I don't think IE supports different units which is why it "works" there.
Please close the path tag in u r sample.
I have made an svg and added it to my page but it has some rather unusual behaviour, as the page is loading I can see the SVG on the page(looks fine the gradients are showing, see below image. Also I have 2 SVG files One the logo and the other the 'K' gets hidden after loading).
After the page loads however for some reason the gradients disappear and I am left with black ascenders and descenders. (see Below)
But things get weirder still as if I click the green circle button, it causes the side bar to collapse Angular then hides the 'Logo' SVG and displays the 'K' SVG. I only have to hit this toggle once and it correctly the gradient issue. I can hide the 'K' & show the 'Logo' again and everything is perfectly fine. See below image of after toggling hide/show of sidebar.
Here is the SVG Code perhaps it is something it? I would really love some help with this it is very strange behaviour and I am not really sure how to solve it.
Logo SVG:
<!-- BEGIN LOGO SVG -->
<div class="logo" ng-hide="sidebarCollapsed">
<svg version="1.1" id="logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 443.7 1602 312.6" style="enable-background:new 0 443.7 1602 312.6;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#accend_1_);}
.st1{fill:url(#decend_1_);}
.st2{fill:#FFFFFF;}
</style>
<g id="k">
<linearGradient id="accend_1_" gradientUnits="userSpaceOnUse" x1="-6.7993" y1="1185.7142" x2="42.6791" y2="1114.1494" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="accend" class="st0" points="78.4,582.9 78.4,445 0,445 0,707.1 79,582.9 "/>
<linearGradient id="decend_1_" gradientUnits="userSpaceOnUse" x1="72.7276" y1="1092.825" x2="1.3943" y2="1202.1583" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="decend" class="st1" points="146.1,596.7 105,658.2 162.4,749.1 253.6,749.1 "/>
<polygon id="branch" class="st2" points="78.4,699.2 78.4,750 0.3,750 0.3,707.1 165.2,444.7 247,444.7 "/>
</g>
<g id="i_1_">
<rect id="title" x="280.3" y="443.7" class="st2" width="68.3" height="52"/>
<rect id="stalk" x="280.3" y="519.9" class="st2" width="68.3" height="228.9"/>
</g>
<path id="n" class="st2" d="M541.7,749.1V624c0-25.7-5-47.3-35.7-47.3c-31.7,0-39.2,20.7-39.2,48v124.5h-68.7V520.2h64v24.5h0.9
c14.4-23.5,34.8-32.3,62.4-32.3c19.4,0,43.6,7.5,58.6,19.8c21.9,18.2,26.3,47,26.3,74v143.3h-68.7V749.1z"/>
<path id="d" class="st2" d="M830.8,445v94.4c-18.8-19.1-41.7-27.3-68-27.3c-69,0-113.8,55.2-113.8,121.6
c0,67.7,44.2,122.6,114.4,122.6c27,0,53.9-10.3,68.3-32.3h5.6v21.9h62.7V445H830.8L830.8,445z M774,692.6
c-34.2,0-57.4-25.7-57.4-58.9s25.1-57.4,58.3-57.4c32.9,0,57.7,24.5,57.7,57.4C832.7,667.2,808.2,692.6,774,692.6z"/>
<path id="r" class="st2" d="M1015.1,623v125.7h-68.3V519.9h64.3v24.5h0.9c11.9-23.5,31-32.3,57.4-32.3v69
C1038.9,582,1015.1,587.6,1015.1,623z"/>
<path id="e" class="st2" d="M1322,637.2c0-69-50.8-125.1-121-125.1c-67.1,0-120.1,56.4-120.1,122.9c0,66.8,54.5,121.3,121.3,121.3
c51.4,0,91.9-32.3,111.9-79.3H1244c-11.3,15.7-23.2,21.3-41.7,21.3c-27,0-49.5-11.9-53.6-43.3h171.5
C1321.4,651.9,1322,643.1,1322,637.2z M1149.6,608c5.3-21.9,27.3-39.2,52-39.2c24.8,0,46.7,17.2,52,39.2H1149.6z"/>
<path id="dlast" class="st2" d="M1533,445v94.4c-18.8-19.1-42.3-27.3-69-27.3c-69,0-114.1,55.2-114.1,121.6
c0,67.7,44.2,122.6,114.4,122.6c27,0,53.6-10.3,68-32.3h3.8v21.9h65.8V445H1533L1533,445z M1475,692.6c-34.2,0-57.4-25.7-57.4-58.9
s25.1-57.4,58.3-57.4c33.2,0,57.7,24.5,57.7,57.4C1533.7,667.2,1509.2,692.6,1475,692.6z"/>
</svg>
</div>
<!-- END LOGO SVG -->
'K' SVG:
<!-- BEGIN MARK SVG -->
<div class="mark" ng-show="sidebarCollapsed">
<svg version="1.1" id="mark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 444.7 253.6 305.4" style="enable-background:new 0 444.7 253.6 305.4;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#accend_1_);}
.st1{fill:url(#decend_1_);}
.st2{fill:#FFFFFF;}
</style>
<g id="k">
<linearGradient id="accend_1_" gradientUnits="userSpaceOnUse" x1="-6.7993" y1="1185.7142" x2="42.6791" y2="1114.1494" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="accend" class="st0" points="78.4,582.9 78.4,445 0,445 0,707.1 79,582.9 "/>
<linearGradient id="decend_1_" gradientUnits="userSpaceOnUse" x1="72.7276" y1="1092.825" x2="1.3943" y2="1202.1583" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="decend" class="st1" points="146.1,596.7 105,658.2 162.4,749.1 253.6,749.1 "/>
<polygon id="branch" class="st2" points="78.4,699.2 78.4,750 0.3,750 0.3,707.1 165.2,444.7 247,444.7 "/>
</g>
</svg>
</div>
<!-- END MARK SVG -->
If the SVGs look okay when viewed in the browser, then it is unlikely to be the SVGs themselves.
My first suspicion would fall on the JS in your webapp and/or the way you are including the SVGs on your page.
How are the SVGs added to your page? Are the included using an <img> or <object>, or are you including them inline in your page? If it's the latter, then I would suggest the likely cause is the fact that you have duplicate id attributes in your SVGs. For example, both SVGs have gradients named accend_1_ and decend_1_. All ids need to be unique. Try giving them different ids.
If you are not inlining them, then please supply more information about how you are using them.
You have multiple elements with the same id value in the html file from each SVG fragment you are including for instance you have two different linearGradient elements both having id="accend_1_" This is invalid. All id values must be unique within a file.