This commit is contained in:
2026-07-18 16:18:22 +02:00
parent 4dc7f10ae2
commit 84c3f1ccda

View File

@@ -11321,31 +11321,41 @@ document.addEventListener('keydown', (e) => {
y: rect.top + rect.height / 2 y: rect.top + rect.height / 2
}; };
const dxCenter = center.x - activeCenter.x;
const dyCenter = center.y - activeCenter.y;
const absDx = Math.abs(dxCenter);
const absDy = Math.abs(dyCenter);
let isCandidate = false; let isCandidate = false;
let primaryDist = 0; let primaryDist = 0;
let secondaryDist = 0; let secondaryGap = 0;
if (e.key === 'ArrowRight') { if (e.key === 'ArrowRight') {
isCandidate = center.x > activeCenter.x; // Must be to the right, and within a 60 degree cone
primaryDist = center.x - activeCenter.x; isCandidate = dxCenter > 0 && absDx >= absDy * 0.5;
secondaryDist = Math.abs(center.y - activeCenter.y); primaryDist = absDx;
// Gap on the Y axis. If they overlap, gap is 0
secondaryGap = Math.max(0, Math.max(activeRect.top, rect.top) - Math.min(activeRect.bottom, rect.bottom));
} else if (e.key === 'ArrowLeft') { } else if (e.key === 'ArrowLeft') {
isCandidate = center.x < activeCenter.x; isCandidate = dxCenter < 0 && absDx >= absDy * 0.5;
primaryDist = activeCenter.x - center.x; primaryDist = absDx;
secondaryDist = Math.abs(center.y - activeCenter.y); secondaryGap = Math.max(0, Math.max(activeRect.top, rect.top) - Math.min(activeRect.bottom, rect.bottom));
} else if (e.key === 'ArrowDown') { } else if (e.key === 'ArrowDown') {
isCandidate = center.y > activeCenter.y; isCandidate = dyCenter > 0 && absDy >= absDx * 0.5;
primaryDist = center.y - activeCenter.y; primaryDist = absDy;
secondaryDist = Math.abs(center.x - activeCenter.x); secondaryGap = Math.max(0, Math.max(activeRect.left, rect.left) - Math.min(activeRect.right, rect.right));
} else if (e.key === 'ArrowUp') { } else if (e.key === 'ArrowUp') {
isCandidate = center.y < activeCenter.y; isCandidate = dyCenter < 0 && absDy >= absDx * 0.5;
primaryDist = activeCenter.y - center.y; primaryDist = absDy;
secondaryDist = Math.abs(center.x - activeCenter.x); secondaryGap = Math.max(0, Math.max(activeRect.left, rect.left) - Math.min(activeRect.right, rect.right));
} }
if (isCandidate) { if (isCandidate) {
// Weight secondary distance heavily to prioritize items directly in the travel path // Massive penalty for gap to force it to pick overlapping items (same row/col)
const distance = primaryDist + (secondaryDist * 5); // Tiny penalty for center misalignment so ties are broken cleanly
const centerMisalignment = (e.key === 'ArrowLeft' || e.key === 'ArrowRight') ? absDy : absDx;
const distance = primaryDist + (secondaryGap * 15) + (centerMisalignment * 0.1);
if (distance < minDistance) { if (distance < minDistance) {
minDistance = distance; minDistance = distance;
bestMatch = thumb; bestMatch = thumb;