JSFiddle - React, Tailwind, and code Playground
by Shawn Allen
HTML
<svg width="400" height="400"></svg>
CSS
svg {
border: 1px solid #ccc;
}
line {
/* stroke: black; */
stroke-opacity: .8;
stroke-linecap: round;
/* stroke-width: 1; */
}
JavaScript
var svg = d3.select("svg"),
bg = svg.append("rect")
.attr({
x: 0,
y: 0,
width: "100%",
height: "100%",
fill: "none"
}),
drawing = false,
pos = {x: 0, y: 0},
lines = [],
lineIndex = 0,
maxLines = 180;
svg.on("mousedown", function(d, i) {
drawing = true;
pos = getPosition();
});
svg.on("mousemove", function() {
if (!drawing) return;
var prev = pos;
pos = getPosition();
var dist = distance(prev, pos);
var color = "hsl(" + [lineIndex++, "100%", "80%"] + ")";
var line = {
x1: prev.x,
y1: prev.y,
x2: pos.x,
y2: pos.y,
"stroke": color,
"stroke-width": dist
};
svg.append("line")
.datum(line)
.attr(line);
lines.push(line);
if (lines.length > maxLines) {
svg.select("line").remove();
lines.shift();
}
bg.attr("fill", lines[0].stroke);
});
svg.on("mouseup", function() {
drawing = false;
});
svg.on("dblclick", function() {
svg.selectAll("line").remove();
});
function getPosition() {
var e = d3.event;
return {x: e.offsetX, y: e.offsetY};
}
function distance(a, b) {
var dx = b.x - a.x,
dy = b.y - a.y;
return Math.sqrt(dx * dx + dy * dy);
}