rotation edge case

This commit is contained in:
Simon
2026-06-23 21:42:29 +00:00
parent f5bb33521e
commit 5aa95e90d4
3 changed files with 98 additions and 8 deletions

View File

@@ -749,15 +749,58 @@ App.videos = App.videos || {};
update();
};
// Records the topmost card crossing (or just below) the viewport top,
// plus how far its top sits from the viewport top. A column re-pack (on
// resize / orientation change) reassigns every card's position, so the
// raw scrollTop would otherwise point at a different video afterwards.
// Anchoring on the topmost visible card (rather than the centred one)
// is independent of the viewport height, which has *already* changed by
// the time a resize/orientation event fires -- so it stays correct even
// as portrait<->landscape swaps the height out from under us.
const captureAnchor = function() {
let anchor = null;
let bestTop = Infinity;
mounted.forEach((card, i) => {
const rect = card.getBoundingClientRect();
if (rect.bottom <= 0) return; // fully scrolled past
if (rect.top < bestTop) {
bestTop = rect.top;
anchor = { index: i, offsetTop: rect.top };
}
});
return anchor;
};
// Scrolls so the anchored card sits at the same viewport offset it had
// before the re-pack, keeping the user's place across the layout change.
const restoreAnchor = function(anchor) {
if (!anchor) return;
const el = grid();
const l = layout[anchor.index];
if (!el || !l) return;
const gridTopDoc = el.getBoundingClientRect().top + window.scrollY;
const target = gridTopDoc + l.top - anchor.offsetTop;
window.scrollTo(0, Math.max(0, target));
};
let resizeRaf = null;
let pendingAnchor = null;
const ensureInit = function() {
if (!cols) measureMetrics();
if (initialized) return;
initialized = true;
window.addEventListener('scroll', scheduleUpdate, { passive: true });
window.addEventListener('resize', () => {
// Capture before the re-pack (positions are still the old ones)
// and keep the earliest anchor across a burst of resize events.
if (!pendingAnchor) pendingAnchor = captureAnchor();
if (resizeRaf) cancelAnimationFrame(resizeRaf);
resizeRaf = requestAnimationFrame(relayout);
resizeRaf = requestAnimationFrame(() => {
resizeRaf = null;
relayout();
restoreAnchor(pendingAnchor);
pendingAnchor = null;
});
});
};