Daydream is a SvelteKit playground that turns pasted code into Mermaid diagrams via Claude. You paste a snippet into the editor, it comes back as a rendered diagram, and an edit mode lets you drop draggable text annotations and freehand highlight strokes directly on top of the result without touching the underlying Mermaid source.
The freehand strokes are the more interesting part. Pointer move events fire far more often than the annotation actually needs, so raw input is decimated by minimum distance before it's stored as a path: each new point is only kept if it's far enough from the last one that was kept, which throws away redundant points from slow drags while keeping fast ones detailed.
function dist2(a: PathPoint, b: PathPoint) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return dx * dx + dy * dy;
}
function decimatePoints(points: PathPoint[], minDistPct: number): PathPoint[] {
if (points.length <= 2) return points;
const out: PathPoint[] = [points[0]];
const minDist2 = minDistPct * minDistPct;
let last = points[0];
for (let i = 1; i < points.length - 1; i++) {
const p = points[i];
if (dist2(p, last) >= minDist2) {
out.push(p);
last = p;
}
}
out.push(points[points.length - 1]);
return out;
}
function pathToD(points: PathPoint[]): string {
if (!points.length) return '';
let d = `M ${points[0].x} ${points[0].y}`;
for (let i = 1; i < points.length; i++) d += ` L ${points[i].x} ${points[i].y}`;
return d;
}
Comparing squared distance against a squared threshold avoids a square root on every pointer move, and the decimated points feed straight into an SVG path string. The stroke annotation is just an <path> element sitting in the same coordinate space as the diagram, which is also what makes it draggable and resizable alongside the text annotations.