mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-11-03 11:42:23 +01: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
@@ -0,0 +1,35 @@
|
||||
// Pure aspect-fitting geometry for the editor. When a whole-image resize is
|
||||
// asked for a target aspect that differs from the current image, content must
|
||||
// be cropped to that aspect (centred on a focus point) and then scaled
|
||||
// UNIFORMLY — never stretched.
|
||||
//
|
||||
// aspectFitCropRect returns the document-space rectangle to crop FIRST so a
|
||||
// subsequent uniform scale-to-{targetW,targetH} preserves the subject aspect
|
||||
// ratio. Returns the full image unchanged when the aspect already matches.
|
||||
|
||||
export function aspectFitCropRect({ width, height, focusX, focusY, targetAspect, tolerance = 0.005 } = {}) {
|
||||
const w = Number(width);
|
||||
const h = Number(height);
|
||||
const a = Number(targetAspect);
|
||||
if (!(w > 0) || !(h > 0) || !(a > 0)) return null;
|
||||
const curAspect = w / h;
|
||||
if (Math.abs(curAspect - a) / a <= tolerance) return { x: 0, y: 0, width: Math.round(w), height: Math.round(h) };
|
||||
const fx = Number.isFinite(Number(focusX)) ? Number(focusX) : w / 2;
|
||||
const fy = Number.isFinite(Number(focusY)) ? Number(focusY) : h / 2;
|
||||
let cw;
|
||||
let ch;
|
||||
if (curAspect > a) {
|
||||
ch = h;
|
||||
cw = Math.max(1, Math.round(ch * a));
|
||||
} else {
|
||||
cw = w;
|
||||
ch = Math.max(1, Math.round(cw / a));
|
||||
}
|
||||
let x = Math.round(fx - cw / 2);
|
||||
let y = Math.round(fy - ch / 2);
|
||||
x = Math.max(0, Math.min(w - cw, x));
|
||||
y = Math.max(0, Math.min(h - ch, y));
|
||||
return { x, y, width: cw, height: ch };
|
||||
}
|
||||
|
||||
export default { aspectFitCropRect };
|
||||
Reference in New Issue
Block a user