2023-04-23 13:42:02 +02:00

74 lines
1.6 KiB
JavaScript

(function () {
const svg = document.querySelector("svg");
const path = svg.querySelector("path");
const circles = toArray(svg.querySelectorAll("circle"));
let draggedCircle = null;
function update() {
const points = circles.map((circle) => ({
x: parseFloat(circle.getAttribute("cx")),
y: parseFloat(circle.getAttribute("cy")),
}));
path.setAttribute("d", toSvgPath(points));
const event = new CustomEvent("myPointsChanged", { detail: points });
document.dispatchEvent(event);
make_base();
}
/**
* Event handlers
*/
svg.addEventListener("mousedown", (event) => {
if (circles.includes(event.target)) {
draggedCircle = event.target;
}
});
document.addEventListener("mousemove", (event) => {
if (draggedCircle) {
const { height, left, top, width } = svg.getBoundingClientRect();
const x = clamp(event.clientX - left, 0, width);
const y = clamp(event.clientY - top, 0, height);
draggedCircle.setAttribute("cx", x);
draggedCircle.setAttribute("cy", y);
update();
}
});
document.addEventListener("mouseup", () => {
draggedCircle = null;
});
document.addEventListener("DOMContentLoaded", () => {
update();
});
/**
* Helpers
*/
function clamp(value, min, max) {
return Math.max(min, Math.min(value, max));
}
function toArray(value) {
return Array.prototype.slice.call(value);
}
function toSvgOperation(operation, { x, y }) {
return `${operation} ${x} ${y}`;
}
function toSvgPath(points) {
return [
toSvgOperation("M", points[points.length - 1]),
...points.map((point) => toSvgOperation("L", point)),
].join(" ");
}
})();