fix(studio): the strip stands on the frame in hand when the rail changes width
A narrower rail is not the wide one with less of the roll in it: its frames are a different number of pixels wide, so the scrollLeft the reader was standing on is a different frame. Opening the studio on a desk and switching to the phone layout left the strip standing further down the roll than the frame on the stage — with three hundred frames in the folder, frame 170 where frame 150 was open — and the frames of the open photo were off the rail. The rail is now put back on the frame in hand whenever its own width changes, the window is read from where it then stands, and the tiles the reader is being shown are the ones asked for.
This commit is contained in:
@@ -92,12 +92,18 @@ export const Filmstrip = memo(function Filmstrip({
|
||||
// and not `scroll-behavior: smooth` on the rail, which glides across the whole
|
||||
// roll: a scroll event a frame, and a fresh window asked for at each one, of
|
||||
// frames the reader never stops on. The rail is put where it is wanted.
|
||||
useEffect(() => {
|
||||
const centre = useCallback(() => {
|
||||
const box = rail.current;
|
||||
const el = box?.children[at] as HTMLElement | undefined;
|
||||
if (!box || !el) return;
|
||||
box.scrollLeft = el.offsetLeft - box.clientWidth / 2 + el.clientWidth / 2;
|
||||
}, [at, frames]);
|
||||
}, [at]);
|
||||
|
||||
useEffect(() => {
|
||||
centre();
|
||||
// The frames are in the dependency too: the frame in hand is a child of the
|
||||
// rail, and until the folder arrives there is nothing to stand on.
|
||||
}, [centre, frames]);
|
||||
|
||||
// Scrolling and resizing both move what the rail can reach: the phone's rail
|
||||
// is a different window on the same roll, and the tiles it now needs are not
|
||||
@@ -115,14 +121,23 @@ export const Filmstrip = memo(function Filmstrip({
|
||||
report();
|
||||
});
|
||||
};
|
||||
// A narrower rail is not the wide one with less of the roll in it: it is a
|
||||
// different number of frames to the pixel the reader was standing on, so the
|
||||
// same scrollLeft is a different frame — the strip left the frame on the
|
||||
// stage behind and drew the roll from somewhere else down it. It is put back
|
||||
// on that frame first, and the window is read from where it then stands.
|
||||
const resized = () => {
|
||||
centre();
|
||||
again();
|
||||
};
|
||||
box.addEventListener('scroll', again, { passive: true });
|
||||
const ro = new ResizeObserver(again);
|
||||
const ro = new ResizeObserver(resized);
|
||||
ro.observe(box);
|
||||
return () => {
|
||||
box.removeEventListener('scroll', again);
|
||||
ro.disconnect();
|
||||
};
|
||||
}, [report]);
|
||||
}, [report, centre]);
|
||||
|
||||
return (
|
||||
// A wheel has no sideways axis, so a plain tick over the roll walks it along.
|
||||
|
||||
Reference in New Issue
Block a user