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="transparent"/>
</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?
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.
I had this problem as well, so I created a library to assist in the creation of gradients that follow along a path
. You can use it standalone in Javascript or alongside D3.js if you prefer. The library is 100% based off of Mike Bostock's work referenced in the first answer, but I've removed D3 as a required dependency.
I've also written a brief tutorial on Medium describing the backstory and usage..
Another way is to make two half circles and apply the opposite linear gradient to each's stroke, and make sure they are both contained in a g element. (In my example the combined gradient isn't 270 degrees but 360. Two half-circles are stacked vertically. The first gradient (applied to the top semi-circle's stroke) would be 100-50% opacity, then the next would have 0% to 50%. Both gradients have the unit vector set to x1,y1,y2=0 and x2=1, making them run from left to right.) Then apply transform=rotate(deg,ctrX,ctrY) to the g.
path{
fill : url(#gradient)
}
<svg width="660" height="220">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#05a"/>
<stop offset="100%" stop-color="#0a5"/>
</linearGradient>
</defs>
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
来源:https://stackoverflow.com/questions/14633363/can-i-apply-a-gradient-along-an-svg-path