Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG Line with Gradient Stroke Won't Display Straight

Tags:

gradient

svg

line

I'm attempting to replicate an <hr> with SVG. Now, making a straight line with SVG works perfectly, but the second I stroke it with a gradient it will no longer display in a straight line.

The following code works, but take note, y1 and y2 must be 1 unit apart. If I set y1 and y2 to 210 for instance, the line will disappear.

<defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" style="stop-color:rgba(0,0,0,0);stop-opacity:0" />
        <stop offset="50%" style="stop-color:rgba(0,0,0,0.75);stop-opacity:1" />
        <stop offset="100%" style="stop-color:rgba(0,0,0,0);stop-opacity:0" />
    </linearGradient>
</defs>
<line x1="40" y1="210" x2="460" y2="211" stroke="url(#grad1)" stroke-width="1" />

I'm probably just missing some obvious function of linear gradients, and the line looks alright, but I'd much rather just have it straight. Thanks.

like image 485
foxandsticks Avatar asked Feb 07 '14 21:02

foxandsticks


People also ask

Can SVG handle gradients?

SVG provides for two types of gradients: linear gradients and radial gradients. Once defined, gradients are then referenced using 'fill' or 'stroke' properties on a given graphics element to indicate that the given element shall be filled or stroked with the referenced gradient.

How do you do linear gradient in SVG?

To use a gradient, we have to reference it from an object's fill or stroke attributes. This is done the same way you reference elements in CSS, using a url . In this case, the url is just a reference to our gradient, which I've given the creative ID, "Gradient". To attach it, set the fill to url(#Gradient) , and voila!


2 Answers

You are getting caught out by the last paragraph in this part of the SVG specification

Keyword objectBoundingBox should not be used when the geometry of the applicable element has no width or no height, such as the case of a horizontal or vertical line, even when the line has actual thickness when viewed due to having a non-zero stroke width since stroke width is ignored for bounding box calculations. When the geometry of the applicable element has no width or height and objectBoundingBox is specified, then the given effect (e.g., a gradient or a filter) will be ignored.

objectBoundingBox is the default for gradientUnits so you need to use gradientUnits="userSpaceOnUse" and then adjust the values to be appropriate for the different coordinate system.

like image 101
Robert Longson Avatar answered Sep 19 '22 06:09

Robert Longson


Robert Longson gives an excellent explanation. But sometimes userSpaceOnUse is a pain, because it spreads the interpolation over the entire canvas, instead of just the line.

Instead, you could add a tiny amount to the values, to ensure the bbox size is not zero.

For example,

  <line x1="40" y1="210" x2="460" y2="210.001" stroke="url(#grad1)" stroke-width="1" />

will draw a straight line with gradient.

like image 36
John Henckel Avatar answered Sep 19 '22 06:09

John Henckel