All checks were successful
Deploy / Deploy to Production (push) Successful in 12s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.2 KiB
JavaScript
66 lines
2.2 KiB
JavaScript
const YEAR_MIN_WIDTH_REM = 18;
|
|
const YEAR_GAP_THRESHOLD = 2;
|
|
const REM_PER_EXTRA_YEAR = 9;
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const section = document.querySelector('.timeline');
|
|
const scrollArea = section.querySelector('.scroll-area');
|
|
const prevBtn = section.querySelector('.timeline-prev');
|
|
const nextBtn = section.querySelector('.timeline-next');
|
|
const yearEls = Array.from(section.querySelectorAll('.year'));
|
|
|
|
yearEls.forEach((yearEl, index) => {
|
|
const year = parseInt(yearEl.querySelector('h4').textContent);
|
|
const nextYearEl = yearEls[index + 1];
|
|
|
|
let minWidth = YEAR_MIN_WIDTH_REM;
|
|
if (nextYearEl) {
|
|
const nextYear = parseInt(nextYearEl.querySelector('h4').textContent);
|
|
const gap = nextYear - year;
|
|
if (gap > YEAR_GAP_THRESHOLD) {
|
|
minWidth =
|
|
YEAR_MIN_WIDTH_REM + (gap - YEAR_GAP_THRESHOLD) * REM_PER_EXTRA_YEAR;
|
|
}
|
|
}
|
|
|
|
yearEl.style.minWidth = `${minWidth}rem`;
|
|
});
|
|
|
|
const SCROLL_MARGIN = 32;
|
|
|
|
function updateButtons() {
|
|
prevBtn.disabled = scrollArea.scrollLeft <= 0;
|
|
nextBtn.disabled =
|
|
Math.ceil(scrollArea.scrollLeft) + scrollArea.clientWidth >=
|
|
scrollArea.scrollWidth;
|
|
}
|
|
|
|
prevBtn.addEventListener('click', () => {
|
|
const containerRect = scrollArea.getBoundingClientRect();
|
|
const leftmost = yearEls.find(
|
|
(y) => y.getBoundingClientRect().right > containerRect.left
|
|
);
|
|
if (!leftmost) return;
|
|
const rect = leftmost.getBoundingClientRect();
|
|
scrollArea.scrollTo({
|
|
left: scrollArea.scrollLeft + rect.right - containerRect.right + SCROLL_MARGIN,
|
|
behavior: 'smooth',
|
|
});
|
|
});
|
|
|
|
nextBtn.addEventListener('click', () => {
|
|
const containerRect = scrollArea.getBoundingClientRect();
|
|
const rightmost = [...yearEls].reverse().find(
|
|
(y) => y.getBoundingClientRect().left < containerRect.right
|
|
);
|
|
if (!rightmost) return;
|
|
const rect = rightmost.getBoundingClientRect();
|
|
scrollArea.scrollTo({
|
|
left: scrollArea.scrollLeft + rect.left - containerRect.left - SCROLL_MARGIN,
|
|
behavior: 'smooth',
|
|
});
|
|
});
|
|
|
|
scrollArea.addEventListener('scroll', updateButtons, { passive: true });
|
|
requestAnimationFrame(updateButtons);
|
|
});
|