1/** 2 * Magic-wand tool â single-click flood-fill selection on the active 3 * layer's pixels. Shift/Alt modifiers override the persistent mode 4 * toggle for the duration of the click (add / subtract). 5 * 6 * Clicking inside an existing selection with no modifier deselects. 7 * 8 * Wand is selection-only â it doesn't mutate the layer until the user 9 * invokes an action (Erase / Copy / etc.) from the panel. That's why 10 * it has just a `click` handler instead of begin/drag/end. 11 * 12 * @param {{ 13 * activeLayer: () => object | null, 14 * saveState: () => void, 15 * composite: () => void, 16 * wandHits: (cx: number, cy: number) => boolean, 17 * runMagicWand: (cx: number, cy: number, mode: 'replace'|'add'|'subtract') => void, 18 * }} deps 19 */ 20import { state } from '../state.js'; 21import { canvasCoords } from '../canvas-coords.js'; 22 23export function createWandTool({ activeLayer, saveState, composite, wandHits, runMagicWand }) { 24 return { 25 click(e) { 26 const layer = activeLayer(); 27 if (!layer) return; 28 const coords = canvasCoords(e, state.mainCanvas); 29 // Persistent toggle sets the default mode; Shift forces add, Alt 30 // forces subtract regardless of the toggle (modifiers always win). 31 let mode = state.wandMode || 'replace'; 32 if (e.shiftKey) mode = 'add'; 33 else if (e.altKey) mode = 'subtract'; 34 // Click INSIDE the existing selection with no modifier â deselect. 35 if (mode === 'replace' && wandHits(coords.x, coords.y)) { 36 saveState(); 37 state.wandMask = null; 38 state.wandLayerId = null; 39 state.wandLastSeed = null; 40 composite(); 41 return; 42 } 43 runMagicWand(coords.x, coords.y, mode); 44 }, 45 }; 46}
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.