diff --git a/steps/src/dataExplorer.js b/steps/src/dataExplorer.js index 23bf8d9..c31763e 100644 --- a/steps/src/dataExplorer.js +++ b/steps/src/dataExplorer.js @@ -1,6 +1,7 @@ // In src/dataExplorer.js import { appState } from './state.js'; +import { throttle } from './utils.js'; import { canvasContainer, explorerBtn @@ -74,12 +75,12 @@ function hideExplorer() { function switchTab(targetTab) { Object.values(tabs).forEach(tab => { tab.panel.classList.add('hidden'); - tab.btn.classList.remove('border-blue-500'); - tab.btn.classList.add('text-gray-500', 'dark:text-gray-400'); + tab.btn.classList.remove('border-blue-500', 'text-gray-900', 'dark:text-white'); + tab.btn.classList.add('text-gray-500', 'dark:text-gray-400', 'border-transparent'); }); tabs[targetTab].panel.classList.remove('hidden'); - tabs[targetTab].btn.classList.add('border-blue-500'); + tabs[targetTab].btn.classList.add('border-blue-500', 'text-gray-900', 'dark:text-white'); tabs[targetTab].btn.classList.remove('text-gray-500', 'dark:text-gray-400'); footer.classList.toggle('hidden', targetTab !== 'grid'); @@ -126,6 +127,32 @@ function displayInGrid(data, title) { switchTab('grid'); } +// --- START: New Robust Update Logic --- +let throttleTimer = null; +let debounceTimer = null; + +/** + * A custom throttled and debounced function for updating the explorer. + * - It throttles calls to prevent updates more than once every 400ms. + * - It debounces calls to ensure a final, guaranteed update happens 500ms + * after the last call, catching the "end" of a seeking action. + */ +export function throttledUpdateExplorer() { + // Clear any pending final update, as a new call has come in. + clearTimeout(debounceTimer); + + // If we are not currently in a "cool-down" period from a throttled call... + if (!throttleTimer) { + updateExplorer(); // ...execute the update immediately. + // Then, set a cool-down timer to prevent another immediate execution. + throttleTimer = setTimeout(() => { throttleTimer = null; }, 400); // 400ms throttle + } + + // Schedule a final, debounced update for after the interactions stop. + debounceTimer = setTimeout(() => { updateExplorer(); }, 500); // 500ms debounce +} +// --- END: New Robust Update Logic --- + // --- Initialization Function (The file's only export) --- export function initializeDataExplorer() { diff --git a/steps/src/dom.js b/steps/src/dom.js index efebf14..8901f53 100644 --- a/steps/src/dom.js +++ b/steps/src/dom.js @@ -1,5 +1,6 @@ import { appState } from "./state.js"; import { formatUTCTime } from "./utils.js"; +import { throttledUpdateExplorer } from "./dataExplorer.js"; // Also import VIDEO_FPS from constants import { VIDEO_FPS } from "./constants.js"; @@ -156,6 +157,9 @@ export function updateFrame(frame, forceVideoSeek) { // --- End of fix --- if (appState.p5_instance) appState.p5_instance.redraw(); // Redraw radar sketch + // --- NEW: Centralized Explorer Update --- + throttledUpdateExplorer(); + // --- END: Centralized Explorer Update --- if (appState.speedGraphInstance && !appState.isPlaying) // Redraw speed graph if not playing. appState.speedGraphInstance.redraw(); diff --git a/steps/src/main.js b/steps/src/main.js index 052cfd2..1c39907 100644 --- a/steps/src/main.js +++ b/steps/src/main.js @@ -18,7 +18,7 @@ import { zoomSketch } from "./p5/zoomSketch.js"; //import { showExplorer, hideExplorer, displayInGrid } from "./dataExplorer.js"; -import { initializeDataExplorer } from "./dataExplorer.js"; // <-- ADD THIS +import { initializeDataExplorer, throttledUpdateExplorer } from "./dataExplorer.js"; // <-- ADD THIS import { showModal, hideModal, @@ -742,7 +742,6 @@ timelineSlider.addEventListener("input", (event) => { updateFrame(frame, true); appState.mediaTimeStart = videoPlayer.currentTime; appState.masterClockStart = now; - timelineSlider.lastInputTime = now; } // --- 2. Final, Precise Sync (Debounced for reliability) --- @@ -802,6 +801,7 @@ timelineSlider.addEventListener("wheel", (event) => { updatePersistentOverlays(videoPlayer.currentTime); updateDebugOverlay(videoPlayer.currentTime); }, 300); // Wait 300ms after the last scroll event + throttledUpdateExplorer(); }); // In src/main.js, add this new block of event listeners