mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-16 20:02:20 +02:00
Photoshop-parity editor client: layers, selection/masking, brushes,
smart filters, LUT import, Quick Edit, mobile gestures, workspaces,
batch operations, and the service-worker versioning (v978->v1006).
Source: vendor/photocraft (ad1cff44) photo-editor client files, merged
onto upstream/dev (a8c147b2). Conflict resolution documented in
pr_work/A_conflicts.md; editor files taken from vendor/photocraft
(upstream's editor is an earlier snapshot of the same feature).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
1.6 KiB
JavaScript
69 lines
1.6 KiB
JavaScript
/**
|
|
* Vector pen / path tool — click to drop anchors, double-click (or the
|
|
* Finish button / Enter) to close the path. The draft is rendered live as
|
|
* a `shape` layer of type `path`; the caller owns layer creation, geometry
|
|
* updates and cleanup so this module stays free of editor state.
|
|
*/
|
|
|
|
export function createPenPathTool({
|
|
saveState = () => {},
|
|
canvasCoords = () => ({ x: 0, y: 0 }),
|
|
mainCanvas = null,
|
|
ensurePathLayer = () => null,
|
|
drawPath = () => {},
|
|
commitPath = () => {},
|
|
cancelPath = () => {},
|
|
composite = () => {},
|
|
syncToolClearIndicators = () => {},
|
|
} = {}) {
|
|
let draft = null;
|
|
|
|
function addPoint(e) {
|
|
const point = canvasCoords(e, mainCanvas);
|
|
if (!Number.isFinite(point?.x) || !Number.isFinite(point?.y)) return false;
|
|
if (!draft) {
|
|
saveState('Add path');
|
|
const layer = ensurePathLayer();
|
|
if (!layer) return false;
|
|
draft = { layer, points: [point] };
|
|
} else {
|
|
draft.points.push(point);
|
|
}
|
|
drawPath(draft.layer, draft.points);
|
|
composite();
|
|
return true;
|
|
}
|
|
|
|
function begin(e) {
|
|
addPoint(e);
|
|
if (e && e.detail >= 2) finish();
|
|
return true;
|
|
}
|
|
|
|
function drag() {}
|
|
function end() {}
|
|
|
|
function finish() {
|
|
if (!draft) return false;
|
|
if (draft.points.length >= 2) {
|
|
commitPath(draft.layer, draft.points);
|
|
} else {
|
|
cancelPath(draft.layer);
|
|
}
|
|
draft = null;
|
|
composite();
|
|
syncToolClearIndicators();
|
|
return true;
|
|
}
|
|
|
|
function cancel() {
|
|
if (!draft) return false;
|
|
cancelPath(draft.layer);
|
|
draft = null;
|
|
composite();
|
|
return true;
|
|
}
|
|
|
|
return { begin, drag, end, finish, cancel, hasDraft: () => !!draft };
|
|
}
|