web: the histogram waits to be asked for, the phone's ruler is a finger tall, and its x answers a real press — a 22px strip under a 44px thumb, a histogram that opened over the photo, and a close button whose press the drag's own preventDefault ate
This commit is contained in:
@@ -1719,8 +1719,17 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
|
|||||||
.col[data-col="slider"] input[type="range"] {
|
.col[data-col="slider"] input[type="range"] {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
height: 22px;
|
/* A finger is wider than the ruler. The strip the ticks are drawn on is
|
||||||
|
22px tall, and a thumb that lands a dozen pixels off its centre is on the
|
||||||
|
photo above it or the row below — the drag never begins. The input's own
|
||||||
|
box is the target, so it grows to the finger; the track inside it keeps
|
||||||
|
the 22px the ruler is read at, because the pseudo-elements below set that
|
||||||
|
height themselves. touch-action none because the drag belongs to the
|
||||||
|
knob: nothing here may be taken for a scroll, a pull-to-refresh or a
|
||||||
|
URL-bar slide instead, and this row sits where those begin. */
|
||||||
|
height: 44px;
|
||||||
background: none;
|
background: none;
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
/* One rule per engine: a grouped selector that names a pseudo-element the
|
/* One rule per engine: a grouped selector that names a pseudo-element the
|
||||||
engine does not know — `-moz-range-track` in Chromium — is dropped whole,
|
engine does not know — `-moz-range-track` in Chromium — is dropped whole,
|
||||||
|
|||||||
@@ -250,6 +250,10 @@ export function Histogram({ url, onClose }: { url: string; onClose: () => void }
|
|||||||
|
|
||||||
const start = (e: React.PointerEvent<HTMLDivElement>) => {
|
const start = (e: React.PointerEvent<HTMLDivElement>) => {
|
||||||
if (e.button !== 0) return;
|
if (e.button !== 0) return;
|
||||||
|
// The × sits in this head but is a button, not a grip: preventDefault here
|
||||||
|
// swallows the click that follows the press (measured — a real click on it
|
||||||
|
// did nothing, while el.click() worked), so the press is left to it.
|
||||||
|
if ((e.target as HTMLElement).closest('.hist-close')) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.currentTarget.setPointerCapture(e.pointerId);
|
e.currentTarget.setPointerCapture(e.pointerId);
|
||||||
|
|||||||
@@ -419,9 +419,9 @@ export function ImageStage({
|
|||||||
// 0.5 is the middle of the photo, which is where the bar starts.
|
// 0.5 is the middle of the photo, which is where the bar starts.
|
||||||
const [split, setSplit] = useState(0.5);
|
const [split, setSplit] = useState(0.5);
|
||||||
const draggingSplit = useRef(false);
|
const draggingSplit = useRef(false);
|
||||||
// The histogram overlay is shown by default and dismissed from its own frame
|
// The histogram overlay is closed when the studio opens and raised from the
|
||||||
// or from the toolbar button; it steps aside while the crop frame is up.
|
// toolbar button or from its own frame; it steps aside while the crop frame is up.
|
||||||
const [showHist, setShowHist] = useState(true);
|
const [showHist, setShowHist] = useState(false);
|
||||||
// Where the eyedropper's own icon is drawing itself: a fraction of the photo,
|
// Where the eyedropper's own icon is drawing itself: a fraction of the photo,
|
||||||
// which is what the layer is, so the stage's zoom cannot scale the offset a
|
// which is what the layer is, so the stage's zoom cannot scale the offset a
|
||||||
// second time and leave the icon drifting away from the cursor.
|
// second time and leave the icon drifting away from the cursor.
|
||||||
|
|||||||
Reference in New Issue
Block a user