Skip to content

Instantly share code, notes, and snippets.

@plmrry
Last active November 20, 2015 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plmrry/25e5d1370ff8fbcd6c24 to your computer and use it in GitHub Desktop.
Save plmrry/25e5d1370ff8fbcd6c24 to your computer and use it in GitHub Desktop.
Simple Gradient Along Stroke

A less-sophisticated alternative to Mike Bostock's Gradient Along Stroke.

Note that this version does not compute mitre joints, so sharp bends reveal the segmented nature of the "path."

<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<meta charset="utf-8">
</head>
<body>
<script src="script.js"></script>
</body>
</html>
var margin = { top: 50, left: 50, bottom: 50, right: 50 },
width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.top - margin.bottom,
vbWidth = width + margin.left + margin.right,
vbHeight = height + margin.top + margin.bottom;
var main = d3.select("body").append("main")
.style({ width: "90%", margin: "0 auto 0 auto" })
.append("svg")
.attr({ viewBox: "0 0 " + vbWidth + " " + vbHeight })
.append("g")
.attr({
transform: "translate(" + [margin.left, margin.top] + ")"
});
main.append("rect").attr({
width: width, height: height, fill: "none"
});
var random = d3.random.normal();
var data = d3.range(10).map(function(d) {
return { x: random(), y: random() };
});
var x = d3.scale.linear()
.domain(d3.extent(data, function(d) { return d.x; }))
.range([0, width]);
var y = d3.scale.linear()
.domain(d3.extent(data, function(d) { return d.y; }))
.range([0, height]);
var dots = main.selectAll(".dot").data(data);
dots.enter().append("circle").classed("dot", true)
.attr({ r: 5 })
.style({ opacity: 0.2 })
dots.attr({
cx: function(d) { return x(d.x); },
cy: function(d) { return y(d.y); }
});
var line = d3.svg.line().interpolate("basis")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
var points = getPoints(line(data), 2);
var segs = [];
points.reduce(function(prev, curr) {
segs.push({
x1: prev.x, y1: prev.y, x2: curr.x, y2: curr.y, t: curr.t
});
return curr;
});
var segmentContainer = main.selectAll(".segments").data([segs]);
segmentContainer.enter().append("g").classed("segments", true);
var segments = segmentContainer.selectAll(".segment").data(Object);
segments.enter().append("line");
var i = d3.interpolateRgb("green", "red");
segments
.attr({
x1: function(d) { return d.x1; }, y1: function(d) { return d.y1; },
x2: function(d) { return d.x2; }, y2: function(d) { return d.y2; },
stroke: function(d) { return i(d.t); },
"stroke-width": 10, "stroke-opacity": 0.1
})
.transition()
.delay(function(d, i) { return i; })
.attr("stroke-opacity", 1);
segments.exit().remove();
// Based on: //gist.github.com/mbostock/4163057
// Sample the SVG path string "d" uniformly with the specified precision.
function getPoints(d, step) {
var path = document.createElementNS(d3.ns.prefix.svg, "path");
path.setAttribute("d", d);
var length = path.getTotalLength();
return d3.range(0, length, step)
.map(function(t) {
var point = path.getPointAtLength(t);
return { x: point.x, y: point.y, t: t/length };
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment