viewof features = {
const svg = DOM.svg(width, height);
const features = [];
svg.value = { type: "FeatureCollection", features };
const path = geoCurvePath(d3.curveBasis);
function clear() {
features.splice(0, features.length);
draw();
}
function draw() {
svg.dispatchEvent(new CustomEvent('input'));
d3.select(svg)
.attr("fill", "none")
.attr("stroke-width", 2)
.selectAll("path")
.data(features)
.join("path")
.attr("fill-opacity", .1)
.attr("fill", d => d.properties.color)
.attr("stroke", d => d.properties.color)
.attr("d", path);
}
d3.select(svg)
.on("touchmove", e => e.preventDefault())
.on("pointerenter", () => (svg.dbltap = svg.dbltap || trackDbltap()))
.on("pointerdown", e => {
if (svg.dbltap(e)) return clear();
trackPointer(e, {
start: p =>
features.push({
type: "Feature",
properties: { color: d3.hsl(360 * Math.random(), 0.9, 0.7).hex() },
geometry: { type: "LineString", coordinates: p.line = [] }
}),
move: p => {
const z = 2 * p.sourceEvent.pressure || 1;
p.line.push([...p.point, z]);
draw();
}
});
});
return svg;
}