问题
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?
回答1:
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.
回答2:
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.
回答3:
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..
回答4:
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.
回答5:
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