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:
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.
path{ fill : url(#gradient) }
path
CSS Images Module - Level 4 has introduced conic-gradient. According to MDN, it's supported in all major browsers except IE.
Although it's not, technically, a gradient along a path, since your path is a circle, the desired outcome can be achieved with:
.loader { --size: 7.5rem; --stroke-size: .5rem; --diff: calc(calc(var(--size)/2) - var(--stroke-size)); background-image: conic-gradient(transparent 25%, red); width: var(--size); height: var(--size); border-radius: 50%; -webkit-mask:radial-gradient(circle var(--diff),transparent 98%,#fff 100%); mask:radial-gradient(circle var(--diff),transparent 98%,#fff 100%); animation: rotate 1.2s linear infinite; margin: 0 auto; } @keyframes rotate { from { transform: rotate(0); } to { transform: rotate(1turn); } } body { background: #f9fcfc url(https://picsum.photos/id/22/1323/880) 100% /cover; margin: 0; min-height: 100vh; padding-top: 2.5rem; } * { box-sizing: border-box; }
The relevant bit is
background-image: conic-gradient(transparent 25%, red);
Note: If not obvious, the CSS variables are not necessary, I just wanted a way to test it at multiple sizes without having to modify the values in more than one place.
Note: Masking the inner circle can also be achieved using an <svg />
. I suspect it might have better browser support than mask. But that's outside of this question's scope.
At the time of posting, my example seems to work as expected in latest: Chrome, Firefox and Edge. Haven't tested Safari. Not expecting it to work in any version of IE.
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.
I managed to apply some kind of gradient following https://www.w3schools.com/graphics/svg_grad_radial.asp.
e.g.: Codepen svg multiple path
Success story sharing