Skip to content

Instantly share code, notes, and snippets.

Last active February 9, 2016 02:08
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
One-Way Markers
license: gpl-3.0

Inspired by Tom MacWright’s previous take on one-way line markers, this example adopts a technique from my path tween example: uniform sampling via getPointAtLength. A rendered line is resampled such that each control point is equally spaced along the length of the line. Thus, the desired number of markers are rendered.

<!DOCTYPE html>
<meta charset="utf-8">
#base-path {
fill: none;
stroke: #000;
stroke-width: 1.5px;
#marker-path {
fill: none;
stroke: none;
stroke-width: 1.5px;
marker-mid: url(#marker);
<svg width="960" height="500">
<marker id="marker"
viewBox="0 0 6 6"
<path d="M0,3v-3l6,3l-6,3z"></path>
<path id="base-path"></path>
<path id="marker-path"></path>
<script src="//"></script>
var z = 0.5;
var svg ="svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var x = d3.scale.linear()
.domain([-1.3, 1.3])
.range([0, width]);
var y = d3.scale.linear()
.domain([-1.3, 1.3])
.range([0, height]);
var line = d3.svg.line()
var basePath ="#base-path"),
markerPath ="#marker-path");
d3.timer(function() {
if ((z += 0.001) > 2) z = 0.5;
var path = line(d3.range(0, 12 + .1, .2).map(function(t) { return [x(Math.cos(t * z)), y(Math.sin(t))]; }));
basePath.attr("d", path);
markerPath.attr("d", path).attr("d", resample(20));
// Uniform sampling based on specified pixel distance.
function resample(dx) {
return function() {
var path = this,
l = path.getTotalLength(),
t = [0], i = 0, dt = dx / l;
while ((i += dt) < 1) t.push(i);
return line( {
var p = path.getPointAtLength(t * l);
return [p.x, p.y];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment