I'd like to put a simple loading indicator on my website that's triggered by a script. It should be a simple circle arc that's got a gradient and is spinning while the user is waiting. I haven't tried the animation part, but got stuck on the static styling for now. Here's what I've got so far:
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="100" height="100"> <defs> <linearGradient id="grad1"> <stop offset="0%" stop-color="red"/> <stop offset="100%" stop-color="red" stop-opacity="0" /> </linearGradient> </defs> <path d="M50 10 A40 40 0 1 0 90 50" stroke="url(#grad1)" stroke-width="10" fill="transparent"/> </svg>
It draws the arc, from the top edge anti-clockwise to the right edge (270°), but the gradient is wrong. Instead of following the path so that the beginning (top edge, 0°) is opaque and the end (right edge, 270°) is transparent, the resulting image of the arc stroke is coloured from left to right in screen space.
How can I make the gradient follow my arc path?
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.
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!
Code explanation:The x1, x2, y1,y2 attributes of the <linearGradient> tag define the start and end position of the gradient. The color range for a gradient can be composed of two or more colors. Each color is specified with a <stop> tag. The offset attribute is used to define where the gradient color begin and end.
Mike Bostock figured out a way, though it's not easy: https://bl.ocks.org/mbostock/4163057
Basically, this technique uses getPointAtLength
to slice the stroke into many short strokes, specify interpolated color stops for each, and then apply a gradient to each short stroke between those stops.
Good luck if you're up to the challenge ;)
Edit (July 3rd, 2019):
There is now a library that will help you do exactly what you're looking for. It's not required to use D3, but you're able to if you desire. Here's a tutorial on Medium.
This type of gradient is not easy to achieve in SVG, see SVG angular gradient.
Also, transparent
is not a valid color in SVG. You should state stop-opacity
as in this example: http://jsfiddle.net/WF2CS/
I'm afraid the easiest solution might be a series of small arc paths with varying opacity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With