1/** 2 * Lasso tool â freehand polygon selection. Mouse-down starts a fresh 3 * polygon; every move appends a point and redraws the dashed outline; 4 * mouse-up keeps the selection visible (the panel's action buttons 5 * read `state.lassoPoints` to act on it). 6 * 7 * Owns its own begin/drag/end handlers and reads/writes shared state. 8 * 9 * @param {{ 10 * composite: () => void, 11 * drawLassoOverlay: () => void, 12 * syncToolClearIndicators: () => void, 13 * }} deps 14 */ 15import { state } from '../state.js'; 16import { canvasCoords } from '../canvas-coords.js'; 17 18export function createLassoTool({ composite, drawLassoOverlay, syncToolClearIndicators }) { 19 return { 20 begin(e) { 21 state.lassoPoints = []; 22 state.lassoActive = true; 23 const coords = canvasCoords(e, state.mainCanvas); 24 state.lassoPoints.push(coords); 25 }, 26 27 drag(e) { 28 if (!state.lassoActive) return; 29 e.preventDefault(); 30 const coords = canvasCoords(e, state.mainCanvas); 31 state.lassoPoints.push(coords); 32 // Live overlay: dashed white outline + translucent red fill. 33 composite(); 34 if (state.lassoPoints.length > 1) { 35 state.mainCtx.beginPath(); 36 state.mainCtx.moveTo(state.lassoPoints[0].x, state.lassoPoints[0].y); 37 for (let i = 1; i < state.lassoPoints.length; i++) { 38 state.mainCtx.lineTo(state.lassoPoints[i].x, state.lassoPoints[i].y); 39 } 40 state.mainCtx.closePath(); 41 state.mainCtx.strokeStyle = '#fff'; 42 state.mainCtx.lineWidth = 1 / state.zoom; 43 state.mainCtx.setLineDash([4 / state.zoom, 4 / state.zoom]); 44 state.mainCtx.stroke(); 45 state.mainCtx.setLineDash([]); 46 state.mainCtx.fillStyle = 'rgba(255, 80, 80, 0.15)'; 47 state.mainCtx.fill(); 48 } 49 }, 50 51 end() { 52 state.lassoActive = false; 53 if (state.lassoPoints.length < 3) { 54 state.lassoPoints = []; 55 composite(); 56 syncToolClearIndicators(); 57 return; 58 } 59 // Keep the selection drawn â the panel's action buttons use it. 60 composite(); 61 drawLassoOverlay(); 62 syncToolClearIndicators(); 63 }, 64 }; 65}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.