// Get scroll position const scrollX = window.scrollX; const scrollY = window.scrollY;
// Get target element dimensions and position const targetRect = currentTarget ? currentTarget.getBoundingClientRect() : null;
// Wait for overlay to have dimensions requestAnimationFrame(() => { // Get overlay dimensions const overlayWidth = overlay.offsetWidth; const overlayHeight = overlay.offsetHeight;
// Default position variables let left, top;
// Smart positioning logic if (targetRect) { // Calculate available space in different directions const spaceBelow = viewportHeight - (targetRect.bottom + 10); const spaceRight = viewportWidth - (targetRect.right + 10); const spaceLeft = targetRect.left - 10; const spaceAbove = targetRect.top - 10;
// PRIORITY 1: Position below the target (preferred position) if (spaceBelow >= overlayHeight) { top = targetRect.bottom + 10; // Center horizontally with the target left = targetRect.left + targetRect.width / 2 - overlayWidth / 2; } // PRIORITY 2: Position to the right elseif (spaceRight >= overlayWidth) { left = targetRect.right + 10; // Center vertically with the target top = targetRect.top + targetRect.height / 2 - overlayHeight / 2; } // PRIORITY 3: Position to the left elseif (spaceLeft >= overlayWidth) { left = targetRect.left - overlayWidth - 10; // Center vertically with the target top = targetRect.top + targetRect.height / 2 - overlayHeight / 2; } // PRIORITY 4: Position above elseif (spaceAbove >= overlayHeight) { top = targetRect.top - overlayHeight - 10; // Center horizontally with the target left = targetRect.left + targetRect.width / 2 - overlayWidth / 2; } // PRIORITY 5: If no good position, use a modified version of below // that shows as much of the image as possible else { top = Math.max(10, viewportHeight - overlayHeight - 10); // Center horizontally with the target if possible left = targetRect.left + targetRect.width / 2 - overlayWidth / 2; } } else { // Fallback to cursor position if no target const x = event.clientX; const y = event.clientY; left = x + 20; top = y + 20; }
// Final bounds checking to ensure overlay stays within viewport if (left + overlayWidth > viewportWidth) { left = Math.max(10, viewportWidth - overlayWidth - 10); } if (left < 0) { left = 10; } if (top + overlayHeight > viewportHeight) { top = Math.max(10, viewportHeight - overlayHeight - 10); } if (top < 0) { top = 10; }
// Apply the calculated position (add scroll offset to convert to absolute position) overlay.style.left = `${left + scrollX}px`; overlay.style.top = `${top + scrollY}px`; overlay.style.transform = 'none'; // Reset any transform }); }