This commit is contained in:
2026-07-18 16:15:47 +02:00
parent 3ff1edf8bf
commit 4dc7f10ae2

View File

@@ -11301,43 +11301,62 @@ document.addEventListener('keydown', (e) => {
const active = document.activeElement; const active = document.activeElement;
if (isArrow && active && active.classList.contains('thumb')) { if (isArrow && active && active.classList.contains('thumb')) {
const currentIndex = thumbs.indexOf(active); const activeRect = active.getBoundingClientRect();
if (currentIndex === -1) return; const activeCenter = {
x: activeRect.left + activeRect.width / 2,
y: activeRect.top + activeRect.height / 2
};
let nextIndex = currentIndex; let bestMatch = null;
let minDistance = Infinity;
if (e.key === 'ArrowRight') { thumbs.forEach(thumb => {
nextIndex = currentIndex + 1; if (thumb === active) return;
} else if (e.key === 'ArrowLeft') {
nextIndex = currentIndex - 1;
} else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
const currentRow = thumbs.filter(t => t.offsetTop === active.offsetTop);
const columns = currentRow.length;
let maxCols = columns; const rect = thumb.getBoundingClientRect();
const firstRowTop = thumbs[0].offsetTop; if (rect.width === 0 && rect.height === 0) return;
const firstRow = thumbs.filter(t => t.offsetTop === firstRowTop);
if (firstRow.length > columns) maxCols = firstRow.length;
if (e.key === 'ArrowDown') { const center = {
nextIndex = currentIndex + maxCols; x: rect.left + rect.width / 2,
if (nextIndex >= thumbs.length) { y: rect.top + rect.height / 2
const lastRowTop = thumbs[thumbs.length - 1].offsetTop; };
if (active.offsetTop < lastRowTop) {
nextIndex = thumbs.length - 1; let isCandidate = false;
} else { let primaryDist = 0;
nextIndex = currentIndex; let secondaryDist = 0;
}
} if (e.key === 'ArrowRight') {
} else { isCandidate = center.x > activeCenter.x;
nextIndex = currentIndex - maxCols; primaryDist = center.x - activeCenter.x;
secondaryDist = Math.abs(center.y - activeCenter.y);
} else if (e.key === 'ArrowLeft') {
isCandidate = center.x < activeCenter.x;
primaryDist = activeCenter.x - center.x;
secondaryDist = Math.abs(center.y - activeCenter.y);
} else if (e.key === 'ArrowDown') {
isCandidate = center.y > activeCenter.y;
primaryDist = center.y - activeCenter.y;
secondaryDist = Math.abs(center.x - activeCenter.x);
} else if (e.key === 'ArrowUp') {
isCandidate = center.y < activeCenter.y;
primaryDist = activeCenter.y - center.y;
secondaryDist = Math.abs(center.x - activeCenter.x);
} }
}
if (nextIndex >= 0 && nextIndex < thumbs.length && nextIndex !== currentIndex) { if (isCandidate) {
// Weight secondary distance heavily to prioritize items directly in the travel path
const distance = primaryDist + (secondaryDist * 5);
if (distance < minDistance) {
minDistance = distance;
bestMatch = thumb;
}
}
});
if (bestMatch) {
e.preventDefault(); e.preventDefault();
thumbs[nextIndex].focus(); bestMatch.focus();
thumbs[nextIndex].scrollIntoView({ behavior: 'smooth', block: 'nearest' }); bestMatch.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
} }
} }
}); });