JSFiddle - React, Tailwind, and code Playground
by Shawn Allen
HTML
<svg></svg>
CSS
html, body {
height: 100%;
overflow: hidden;
}
svg {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
line {
stroke-linecap: round;
}
JavaScript
var svg = d3.select("svg"),
path = svg.append("path"),
lines = [],
maxLines = 360,
grid = 1,
draw = drawLines;
var strokeScale = d3.scale.linear()
.domain([0, 200])
.range([20, 5])
.clamp(true);
var strokeWidth = function(line) {
return strokeScale(distance(line.start, line.end));
};
var strokeColor = function(line, i) {
return d3.hsl(i / maxLines * 360, 1, .5);
};
function drawPath() {
var points = [];
lines.forEach(function(line) {
points.push(line.start, line.end);
});
path.datum(points)
.attr("d", d3.svg.line()
.interpolate(interpolate)
.x(function(d) { return round(d.x); })
.y(function(d) { return round(d.y); }));
}
function drawLines() {
var line = svg.selectAll("line")
.data(lines);
line.exit().remove();
line.enter().append("line");
line.attr({
x1: function(d) { return round(d.start.x); },
y1: function(d) { return round(d.start.y); },
x2: function(d) { return round(d.end.x); },
y2: function(d) { return round(d.end.y); }
})
.attr("stroke", strokeColor)
.attr("stroke-width", 20);
}
svg.on("mousedown", function(e) {
var mouse = getPosition();
svg.on("mousemove", function(e) {
var pos = getPosition(),
line = {
start: mouse,
end: pos
};
mouse = pos;
lines.push(line);
if (lines.length > maxLines) {
lines.shift();
}
draw();
});
});
svg.on("mouseup", function() {
svg.on("mousemove", null);
});
svg.on("dblclick", clear);
function clear() {
lines = [];
draw();
}
function getPosition() {
var e = d3.event;
return {
x: e.offsetX,
y: e.offsetY,
time: Date.now()
};
}
function round(n) {
return grid * Math.round(n / grid);
}
function distance(a, b) {
var dx = b.x - a.x,
dy = b.y - a.y;
return Math.sqrt(dx * dx + dy * dy);
}