All folders stick at --stack-reveal; higher layers paint over lower ones. Bodies hidden until panel aligns on the stack line (no vertical list). Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
/** Scroll depth + jump + hide upcoming cards until they cover the stack */
|
|
export function initStackScroll(options = {}) {
|
|
const {
|
|
sectionSelector = '.scroll-section',
|
|
depthEl = document.getElementById('depth'),
|
|
depthPrefix = 'L',
|
|
tabSelector = '[data-goto], .jump',
|
|
panelSelector = '.folder, .layer, .frame, .unit',
|
|
} = options;
|
|
|
|
const sections = document.querySelectorAll(sectionSelector);
|
|
if (!sections.length) return;
|
|
|
|
const reveal = () => {
|
|
const v = getComputedStyle(document.documentElement).getPropertyValue('--stack-reveal').trim();
|
|
return parseFloat(v) || 344;
|
|
};
|
|
|
|
const mid = () => window.innerHeight * 0.42;
|
|
|
|
function updateDepth() {
|
|
const rLine = reveal();
|
|
let active = 0;
|
|
|
|
sections.forEach((sec) => {
|
|
const r = sec.getBoundingClientRect();
|
|
if (r.top <= mid() && r.bottom > mid()) active = Number(sec.dataset.layer);
|
|
});
|
|
|
|
if (depthEl) depthEl.textContent = `${depthPrefix}${active}`;
|
|
|
|
document.querySelectorAll('.stack-ruler button, .stack-ruler [data-goto], .tab-rail button, .tab[data-goto]').forEach((el) => {
|
|
const n = el.dataset.layer ?? el.dataset.goto;
|
|
if (n === undefined) return;
|
|
el.classList.toggle('active', Number(n) === active);
|
|
});
|
|
|
|
sections.forEach((sec) => {
|
|
const layer = Number(sec.dataset.layer);
|
|
const panel = sec.querySelector(panelSelector);
|
|
if (!panel) return;
|
|
|
|
const r = sec.getBoundingClientRect();
|
|
const pr = panel.getBoundingClientRect();
|
|
const onStack = Math.abs(pr.top - rLine) < 10;
|
|
const past = r.bottom <= rLine;
|
|
|
|
sec.classList.toggle('is-active', layer === active);
|
|
sec.classList.toggle('is-stuck', onStack);
|
|
sec.classList.toggle('is-past', past);
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll(tabSelector).forEach((tab) => {
|
|
tab.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
const layer = tab.dataset.goto;
|
|
const target = document.querySelector(`${sectionSelector}[data-layer="${layer}"]`);
|
|
if (!target) return;
|
|
const y = target.getBoundingClientRect().top + window.scrollY - 48;
|
|
window.scrollTo({ top: Math.max(0, y), behavior: 'smooth' });
|
|
});
|
|
});
|
|
|
|
window.addEventListener('scroll', updateDepth, { passive: true });
|
|
window.addEventListener('resize', updateDepth, { passive: true });
|
|
updateDepth();
|
|
}
|