Public
Edited
May 31, 2024
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
points = [
[100, 100],
[400, 100],
[400, 400],
[250, 250],
[100, 400]
]
Insert cell
//
// Canvas and interaction code for editing a polygon
//
function polygonDemo(points, options = {}) {
const {
width = 800,
height = 600,
change = (ctx, points, i) => {},
doubleClick = (ctx, points, i) => {}
} = options;

const canvas = htl.html`<canvas width=${width} height=${height}>`;
const ctx = canvas.getContext("2d");
let selected = -1;
let moved = false;
let mouse;
change(ctx, points, -1);

// Disable context menu
canvas.oncontextmenu = () => {
return false;
};

canvas.onmousedown = function (event) {
mouse = [event.offsetX, event.offsetY];
selected = -1;
let i = 0;
for (let p of points) {
if (vec2.dist(mouse, p) < 8) {
selected = i;
break;
}
i++;
}
if (selected < 0) {
// new point
const n = points.length;
if (n > 2) {
// Find closest line segment where to insert
let minDist = Infinity;
let closest = -1;
for (let i = 0; i < n; i++) {
const p = points[(i - 1 + n) % n];
const q = points[i];
const d = vec2.distSegment(mouse, p, q);
if (d < minDist) {
[minDist, closest] = [d, i];
}
}
points.splice(closest, 0, mouse);
change(ctx, points, closest);
} else {
points.push(mouse);
change(ctx, points, n);
}
} else {
moved = false;
}
};
canvas.onmousemove = function (event) {
moved = true;
if (selected < 0) return;
let newMouse = [event.offsetX, event.offsetY];
let v = vec2.sub([], newMouse, mouse);
vec2.add(points[selected], points[selected], v);
mouse = newMouse;
change(ctx, points, selected);
};
canvas.onmouseup = function (event) {
if (!moved && selected != -1 && points.length > 1) {
// click on point
points.splice(selected, 1);
change(ctx, points, selected);
}
selected = -1;
};
return canvas;
}
Insert cell
import { vec2 } from "@esperanc/vec2-utils"
Insert cell
hobby = import("https://unpkg.com/hobby-curve@0.2.1/dist/index.js?module")
Insert cell
createHobbyBezier = hobby.createHobbyBezier
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more