Instantly share code, notes, and snippets.

# mbostock/.block

Last active March 6, 2024 04:06
Show Gist options
• Save mbostock/4163057 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

This example demonstrates how to create a gradient that follows a stroke. This technique is sometimes used to indicate directionality along a curved edge, such as with hierarchical edge bundling.

To start, take any SVG path element and uniformly sample points along the path using getPointAtLength. (This method can also be used for path tweening.) Then, for each segment between adjacent points, compute the miter joint via line-line intersection. Lastly fill each segment by interpolating the start and end colors, here green to red, using the normalized length t along the path. Although each segment is a constant color, there are many segments to give the appearance of a continuous gradient.

This example uses a thin stroke in addition to filling the segments. This avoids antialiasing artifacts due to most web browsers not implementing full-scene antialiasing.

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters


This is awesome

### trusktr commented Oct 22, 2016 • edited

@mbostock Hi, I tried to do this with a circle made from two arcs, and it almost works but make an extra segment in the middle, which is funky. The starting path is like this:

```  <path fill="none" stroke-width="10" d="
M 100, 100
m -75, 0
a 75,75 0 1,1 150,0
a 75,75 0 1,1 -150,0
"></path>```

and the result looks like this:

### trusktr commented Oct 22, 2016 • edited

Oh, I guess it makes sense mecause of the `m -75, 0` command, but when I draw the arc without applying the interpolation, it looks like this:

```  <path fill="none" stroke-width="10" stroke="blue" d="
M 100, 100
m -75, 0
a 75,75 0 1,1 150,0
a 75,75 0 1,1 -150,0
"></path>```

It also appears that the resulting rainbow gradient is thicker than the original path (compare screenshots).

### trusktr commented Oct 22, 2016 • edited

If I change it to the following with only a single move command, it works fine, although the thickness is still too big:

```  <path fill="none" stroke-width="1" stroke="blue" d="
m 100, 100
a 75,75 0 1,1 150,0
a 75,75 0 1,1 -150,0
"></path>```

EDIT: Ah, the width is the final parameter to`lineJoin`. I suppose it would be possible to make this detect the width instead of having us passing it in (which is redundant since we chose the width in the original path already).

### isaironi commented Nov 9, 2018

Hi,
I used this to make two figure eights, one flipped over the y axis of the other (they move in the opposite direction) .
It works like a charm but I'm a little confused about the color coding. In the doc you said it was green-to-red. It seems to me to be going purple to red to green to blue. It also seems to me like your original image here and the one on display at https://bl.ocks.org/mbostock/4163057 are not the same - the one here is indeed green-to-red, the one there (and the svgs produced by that code) are purple-pink-oranger-green-blue.
Am I right or did I do something wrong in generating my .htmls ? Thanks so much for this script, it worked like a charm :).