import * as THREE from "three"; import { clearCountryBoundaryHover, getShowCountryBoundaries, updateCountryBoundaryHover, } from "./country-boundaries.js"; import { screenToEarthCoords, vector3ToLatLon } from "./utils.js"; const UPDATE_INTERVAL_MS = 120; const MIN_COORD_DELTA_DEGREES = 0.05; const BLOCKING_BODY_CLASSES = [ "earth-mobile-drawer-open", "earth-search-open", "earth-settings-open", "earth-media-open", "earth-info-open", ]; const centerRaycaster = new THREE.Raycaster(); const centerMouse = new THREE.Vector2(); let ownsHighlight = false; let lastUpdateAt = 0; let lastLat = null; let lastLon = null; function isMobileLayout() { return document.body.classList.contains("layout-mode-mobile"); } function hasBlockingForegroundUi() { return BLOCKING_BODY_CLASSES.some((className) => document.body.classList.contains(className), ); } function resetCachedCenter() { lastUpdateAt = 0; lastLat = null; lastLon = null; } export function clearMobileCenterCountryHighlight() { if (ownsHighlight) { clearCountryBoundaryHover(); } ownsHighlight = false; resetCachedCenter(); } function clearAnyMobileCountryHighlight() { clearCountryBoundaryHover(); ownsHighlight = false; resetCachedCenter(); } function shouldSkipForSmallMovement(coords) { if (lastLat === null || lastLon === null) return false; return ( Math.abs(coords.lat - lastLat) < MIN_COORD_DELTA_DEGREES && Math.abs(coords.lon - lastLon) < MIN_COORD_DELTA_DEGREES ); } export function updateMobileCenterCountryHighlight({ camera, earth, renderer, now = performance.now(), isBlocked = false, } = {}) { const mobile = isMobileLayout(); if (!mobile) { clearMobileCenterCountryHighlight(); return null; } if ( !camera || !earth || !renderer?.domElement || isBlocked || hasBlockingForegroundUi() || !getShowCountryBoundaries() ) { clearAnyMobileCountryHighlight(); return null; } if (now - lastUpdateAt < UPDATE_INTERVAL_MS) { return null; } const rect = renderer.domElement.getBoundingClientRect(); if (rect.width <= 0 || rect.height <= 0) { clearMobileCenterCountryHighlight(); return null; } const earthPoint = screenToEarthCoords( rect.left + rect.width / 2, rect.top + rect.height / 2, camera, earth, renderer.domElement, centerRaycaster, centerMouse, ); lastUpdateAt = now; if (!earthPoint) { clearMobileCenterCountryHighlight(); return null; } const coords = vector3ToLatLon(earthPoint); if (shouldSkipForSmallMovement(coords)) { return null; } lastLat = coords.lat; lastLon = coords.lon; ownsHighlight = true; return updateCountryBoundaryHover(coords); }