mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-23 23:32:22 +02:00
feat(photo-editor): Ajax Image Editor client (Photoshop-parity tools)
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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c74f475679
commit
5fac693c1c
@@ -220,16 +220,11 @@ export function wireAIToolsMisc({
|
||||
renderLayerPanel();
|
||||
composite();
|
||||
}
|
||||
const addButton = document.getElementById('ge-add-layer');
|
||||
addButton?.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const buildFxMenu = (anchor) => {
|
||||
document.querySelector('.ge-add-layer-menu')?.remove();
|
||||
const menu = document.createElement('div');
|
||||
menu.className = 'ge-add-layer-menu ge-frosted';
|
||||
menu.innerHTML = `
|
||||
<button type="button" data-layer-kind="raster"><span class="ge-add-layer-symbol">+</span><span>Pixel Layer</span></button>
|
||||
<span class="ge-add-layer-divider"></span>
|
||||
<button type="button" data-adjustment-type="levels"><span class="ge-add-layer-symbol">▥</span><span>Levels</span></button>
|
||||
<button type="button" data-adjustment-type="curves"><span class="ge-add-layer-symbol">⌁</span><span>Curves</span></button>
|
||||
<button type="button" data-adjustment-type="exposure"><span class="ge-add-layer-symbol">☼</span><span>Exposure</span></button>
|
||||
@@ -242,9 +237,16 @@ export function wireAIToolsMisc({
|
||||
<button type="button" data-adjustment-type="color-balance"><span class="ge-add-layer-symbol">◒</span><span>Color Balance</span></button>
|
||||
<button type="button" data-adjustment-type="selective-color"><span class="ge-add-layer-symbol">◎</span><span>Selective Color</span></button>
|
||||
<button type="button" data-adjustment-type="gradient-map"><span class="ge-add-layer-symbol">▰</span><span>Gradient Map</span></button>
|
||||
<span class="ge-add-layer-divider"></span>
|
||||
<button type="button" data-adjustment-type="invert"><span class="ge-add-layer-symbol">◑</span><span>Invert</span></button>
|
||||
<button type="button" data-adjustment-type="posterize"><span class="ge-add-layer-symbol">▤</span><span>Posterize</span></button>
|
||||
<button type="button" data-adjustment-type="threshold"><span class="ge-add-layer-symbol">◧</span><span>Threshold</span></button>
|
||||
<button type="button" data-adjustment-type="photo-filter"><span class="ge-add-layer-symbol">◍</span><span>Photo Filter</span></button>
|
||||
<button type="button" data-adjustment-type="channel-mixer"><span class="ge-add-layer-symbol">⇄</span><span>Channel Mixer</span></button>
|
||||
<button type="button" data-adjustment-type="color-lookup"><span class="ge-add-layer-symbol">▦</span><span>Color Lookup</span></button>
|
||||
`;
|
||||
document.body.appendChild(menu);
|
||||
const rect = addButton.getBoundingClientRect();
|
||||
const rect = anchor.getBoundingClientRect();
|
||||
const menuRect = menu.getBoundingClientRect();
|
||||
menu.style.left = `${Math.max(8, Math.min(window.innerWidth - menuRect.width - 8, rect.right - menuRect.width))}px`;
|
||||
menu.style.top = `${Math.max(8, Math.min(window.innerHeight - menuRect.height - 8, rect.bottom + 5))}px`;
|
||||
@@ -253,7 +255,7 @@ export function wireAIToolsMisc({
|
||||
document.removeEventListener('pointerdown', away, true);
|
||||
};
|
||||
const away = pointerEvent => {
|
||||
if (!menu.contains(pointerEvent.target) && pointerEvent.target !== addButton) close();
|
||||
if (!menu.contains(pointerEvent.target) && pointerEvent.target !== anchor) close();
|
||||
};
|
||||
requestAnimationFrame(() => document.addEventListener('pointerdown', away, true));
|
||||
menu.addEventListener('click', clickEvent => {
|
||||
@@ -261,10 +263,26 @@ export function wireAIToolsMisc({
|
||||
if (!button) return;
|
||||
clickEvent.preventDefault();
|
||||
clickEvent.stopPropagation();
|
||||
if (button.dataset.layerKind === 'raster') addEmptyLayer();
|
||||
else if (button.dataset.adjustmentType) openAdjustmentLayer?.(button.dataset.adjustmentType, addButton);
|
||||
if (button.dataset.adjustmentType) openAdjustmentLayer?.(button.dataset.adjustmentType, anchor);
|
||||
close();
|
||||
});
|
||||
};
|
||||
|
||||
// "+" adds a plain pixel layer directly.
|
||||
const addButton = document.getElementById('ge-add-layer');
|
||||
addButton?.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
document.querySelector('.ge-add-layer-menu')?.remove();
|
||||
addEmptyLayer();
|
||||
});
|
||||
|
||||
// "fx" opens the adjustment-layer chooser.
|
||||
const addFxButton = document.getElementById('ge-add-fx');
|
||||
addFxButton?.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
buildFxMenu(addFxButton);
|
||||
});
|
||||
|
||||
return { addEmptyLayer };
|
||||
|
||||
Reference in New Issue
Block a user