web: keep compare on offer, and compare at the cropped size
Choosing a crop ratio used to disable COMPARE outright, because the split painted the whole original into a box that was now the crop's shape. The original is now looked at through a window of the render's own shape: with a crop applied the photo is scaled and slid by the crop rect so the same rectangle lines up, and the split compares like with like. The window needs the image free to overflow it, so the inline style lifts the box clamp that .canvas-wrap img puts on every preview.
This commit is contained in:
@@ -2472,7 +2472,8 @@ export function Workspace() {
|
||||
cropWH={cropWH}
|
||||
onCropRectChange={setCropRect}
|
||||
onStageZoom={onStageZoom}
|
||||
canCompare={crop === 'none'}
|
||||
canCompare={!!source}
|
||||
compareCrop={cropLive ? cropRect : null}
|
||||
onSaveOriginal={() => void saveOriginal()}
|
||||
onClear={() => setClearing(true)}
|
||||
picking={picking}
|
||||
|
||||
@@ -284,6 +284,9 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
|
||||
cursor: ew-resize;
|
||||
touch-action: none;
|
||||
}
|
||||
/* The window the original is looked at through: the render's own shape, so a
|
||||
crop can slide and scale the photo behind it and still line up. */
|
||||
.compare-window { position: absolute; inset: 0; overflow: hidden; }
|
||||
.compare-orig { position: absolute; inset: 0; width: 100%; height: 100%; box-shadow: none; }
|
||||
.compare-bar {
|
||||
position: absolute;
|
||||
|
||||
@@ -65,6 +65,9 @@ export function ImageStage({
|
||||
onCropRectChange,
|
||||
onStageZoom,
|
||||
canCompare = false,
|
||||
// The crop the render is already carrying: the original is shown through the
|
||||
// same window, so the two halves line up whatever the shape.
|
||||
compareCrop = null,
|
||||
onSaveOriginal,
|
||||
// Takes the photo off the stage. What is on it goes first — the confirmation
|
||||
// offers to file the frame or export it, so nothing is lost by accident.
|
||||
@@ -93,9 +96,11 @@ export function ImageStage({
|
||||
// at — the app re-cuts its preview copy to match. Scaled to contain the
|
||||
// photo and multiplied by the zoom and the screen's pixel ratio.
|
||||
onStageZoom?: (longDevicePx: number) => void;
|
||||
// Compare needs the un-cropped photo on one side and the render on the other,
|
||||
// so it is only offered while the crop is untouched.
|
||||
// Compare puts the photo that was loaded beside the render, and the crop is
|
||||
// part of that render: when one is applied the original is shown through the
|
||||
// same window, so the split stays a straight line-up.
|
||||
canCompare?: boolean;
|
||||
compareCrop?: CropRect | null;
|
||||
// Puts the untouched photo file itself in the owner's hands — on a phone that
|
||||
// is the share sheet, whose "Save Image" is what reaches the photo library.
|
||||
onSaveOriginal?: () => void;
|
||||
@@ -757,7 +762,7 @@ export function ImageStage({
|
||||
{straightenRuler}
|
||||
</div>
|
||||
) : null}
|
||||
{compare && canCompare && originalUrl && box ? (
|
||||
{compare && canCompare && !cropEditing && originalUrl && box ? (
|
||||
<div
|
||||
className="compare-layer"
|
||||
data-key="compare-layer"
|
||||
@@ -775,15 +780,39 @@ export function ImageStage({
|
||||
onPointerCancel={endSplit}
|
||||
>
|
||||
{/* The original is clipped to everything left of the bar; the
|
||||
graded render stays the un-clipped base underneath it. */}
|
||||
<img
|
||||
className="compare-orig"
|
||||
data-key="compare-orig"
|
||||
src={originalUrl}
|
||||
alt=""
|
||||
draggable={false}
|
||||
graded render stays the un-clipped base underneath it. The
|
||||
window is the render's own shape, so when a crop is applied the
|
||||
original is scaled and shifted until that same rectangle fills
|
||||
it — otherwise the split would compare a cropped render with a
|
||||
whole photo. */}
|
||||
<div
|
||||
className="compare-window"
|
||||
style={{ clipPath: `inset(0 ${(1 - split) * 100}% 0 0)` }}
|
||||
/>
|
||||
>
|
||||
<img
|
||||
className="compare-orig"
|
||||
data-key="compare-orig"
|
||||
src={originalUrl}
|
||||
alt=""
|
||||
draggable={false}
|
||||
style={
|
||||
compareCrop
|
||||
? {
|
||||
left: `${(-compareCrop.x / compareCrop.w) * 100}%`,
|
||||
top: `${(-compareCrop.y / compareCrop.h) * 100}%`,
|
||||
width: `${100 / compareCrop.w}%`,
|
||||
height: `${100 / compareCrop.h}%`,
|
||||
right: 'auto',
|
||||
bottom: 'auto',
|
||||
// .canvas-wrap img clamps to the box; the original has
|
||||
// to be free to overflow it so the crop can slide.
|
||||
maxWidth: 'none',
|
||||
maxHeight: 'none',
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="compare-bar"
|
||||
data-key="compare-bar"
|
||||
|
||||
Reference in New Issue
Block a user