Files
odysseus/static/js/editor/tools/lasso.js
pewdiepie-archdaemon e5c99a5eee Odysseus v1.0
2026-05-31 23:58:26 +09:00

66 lines
2.1 KiB
JavaScript

/**
* Lasso tool — freehand polygon selection. Mouse-down starts a fresh
* polygon; every move appends a point and redraws the dashed outline;
* mouse-up keeps the selection visible (the panel's action buttons
* read `state.lassoPoints` to act on it).
*
* Owns its own begin/drag/end handlers and reads/writes shared state.
*
* @param {{
* composite: () => void,
* drawLassoOverlay: () => void,
* syncToolClearIndicators: () => void,
* }} deps
*/
import { state } from '../state.js';
import { canvasCoords } from '../canvas-coords.js';
export function createLassoTool({ composite, drawLassoOverlay, syncToolClearIndicators }) {
return {
begin(e) {
state.lassoPoints = [];
state.lassoActive = true;
const coords = canvasCoords(e, state.mainCanvas);
state.lassoPoints.push(coords);
},
drag(e) {
if (!state.lassoActive) return;
e.preventDefault();
const coords = canvasCoords(e, state.mainCanvas);
state.lassoPoints.push(coords);
// Live overlay: dashed white outline + translucent red fill.
composite();
if (state.lassoPoints.length > 1) {
state.mainCtx.beginPath();
state.mainCtx.moveTo(state.lassoPoints[0].x, state.lassoPoints[0].y);
for (let i = 1; i < state.lassoPoints.length; i++) {
state.mainCtx.lineTo(state.lassoPoints[i].x, state.lassoPoints[i].y);
}
state.mainCtx.closePath();
state.mainCtx.strokeStyle = '#fff';
state.mainCtx.lineWidth = 1 / state.zoom;
state.mainCtx.setLineDash([4 / state.zoom, 4 / state.zoom]);
state.mainCtx.stroke();
state.mainCtx.setLineDash([]);
state.mainCtx.fillStyle = 'rgba(255, 80, 80, 0.15)';
state.mainCtx.fill();
}
},
end() {
state.lassoActive = false;
if (state.lassoPoints.length < 3) {
state.lassoPoints = [];
composite();
syncToolClearIndicators();
return;
}
// Keep the selection drawn — the panel's action buttons use it.
composite();
drawLassoOverlay();
syncToolClearIndicators();
},
};
}