Browse Source

Moving the updateFrame function from dom.js to sync.js. Cleaned up the logic for shortcut key "a" causing errors in console.

refactor/modularize
RUSHIL AMBARISH KADU 6 months ago
parent
commit
83c64dd84c
  1. 96
      steps/src/dom.js
  2. 17
      steps/src/main.js
  3. 101
      steps/src/sync.js

96
steps/src/dom.js

@ -1,10 +1,7 @@
// TODO(sync-refactor): move sync logic into src/sync.js
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";
// --- DOM Element References --- //
export const themeToggleBtn = document.getElementById("theme-toggle");
@ -86,89 +83,6 @@ export const toggleConfirmedOnly = document.getElementById("toggle-confirmed-onl
export const explorerBtn = document.getElementById("explorer-btn");
//----------------------UPDATE FRAME Function----------------------//
// Updates the UI to reflect the current radar frame and synchronizes video playback.
export function updateFrame(frame, forceVideoSeek) {
const startTime = performance.now(); //start emasuring timer of performance.
if (
!appState.vizData ||
frame < 0 ||
frame >= appState.vizData.radarFrames.length
)
// Exit if no visualization data or invalid frame.
return; // Exit if no visualization data or invalid frame
appState.currentFrame = frame;
timelineSlider.value = appState.currentFrame;
frameCounter.textContent = `Frame: ${appState.currentFrame + 1} / ${
appState.vizData.radarFrames.length
}`;
const frameData = appState.vizData.radarFrames[appState.currentFrame];
if (toggleEgoSpeed.checked && frameData) {
// Update ego speed display if enabled.
const egoVy_kmh = (frameData.egoVelocity[1] * 3.6).toFixed(1); // Convert m/s to km/h and format
egoSpeedDisplay.textContent = `Ego: ${egoVy_kmh} km/h`;
egoSpeedDisplay.classList.remove("hidden");
} else {
egoSpeedDisplay.classList.add("hidden"); // Hide ego speed display.
}
// --- ADD THIS NEW BLOCK ---
if (
frameData &&
frameData.canVehSpeed_kmph !== null &&
!isNaN(frameData.canVehSpeed_kmph)
) {
canSpeedDisplay.textContent = `CAN: ${frameData.canVehSpeed_kmph.toFixed(
1
)} km/h`;
canSpeedDisplay.classList.remove("hidden");
} else {
canSpeedDisplay.classList.add("hidden");
}
// --- END OF NEW BLOCK ---
let timeForUpdates = videoPlayer.currentTime; // NEW: Default to the video's current time
if (
forceVideoSeek &&
videoPlayer.src &&
videoPlayer.readyState > 1 &&
appState.videoStartDate &&
frameData
) {
const offsetMs = parseFloat(offsetInput.value) || 0;
const targetRadarTimeMs = frameData.timestampMs;
const targetVideoTimeSec = (targetRadarTimeMs - offsetMs) / 1000;
if (targetVideoTimeSec >= 0 && targetVideoTimeSec <= videoPlayer.duration) {
// Ensure target time is within video duration
if (Math.abs(videoPlayer.currentTime - targetVideoTimeSec) > 0.05) {
// Check for significant drift
videoPlayer.currentTime = targetVideoTimeSec; // Seek video if drift is significant
}
// MODIFIED: Use the calculated target time for our updates, not the stale videoPlayer.currentTime
timeForUpdates = targetVideoTimeSec; // Update time for subsequent UI updates
}
} // End of forceVideoSeek block
if (!appState.isPlaying) {
// MODIFIED: Use our new synchronized time variable
updatePersistentOverlays(timeForUpdates);
}
// --- End of fix ---
// --- START: Conditional Redraw Logic ---
// Only force a redraw from here if the animation loop is NOT running.
// When playing, the animationLoop is responsible for redrawing.
if (!appState.isPlaying && appState.p5_instance) appState.p5_instance.redraw();
if (!appState.isPlaying && appState.speedGraphInstance) appState.speedGraphInstance.redraw();
// --- NEW: Centralized Explorer Update ---
throttledUpdateExplorer();
// --- END: Centralized Explorer Update ---
const endTime = performance.now();
appState.lastFrameRenderTime = endTime - startTime; // <-- End timer and update state
}
//----------------------Reset UI for New file Load----------------------//
// Resets the UI to make sure everything is clean before new files load.
export function resetUIForNewLoad() {
@ -209,16 +123,6 @@ export function resetUIForNewLoad() {
speedGraphPlaceholder.classList.remove('hidden');
}
//----------------------RESET VISUALIZATION Function----------------------//
// Resets the visualization to its initial state.
export function resetVisualization() {
appState.isPlaying = false;
playPauseBtn.textContent = "Play";
const numFrames = appState.vizData.radarFrames.length;
timelineSlider.max = numFrames > 0 ? numFrames - 1 : 0;
updateFrame(0, true); // Update to the first frame and force video seek
}
//----------------------CAN DISPLAY UPDATE Function----------------------//
// Updates the CAN speed display based on the current media time.

17
steps/src/main.js

@ -34,6 +34,8 @@ import {
stopPlayback,
forceResyncWithOffset,
initSyncUIHandlers,
updateFrame,
resetVisualization,
handleTimelineInput,
} from "./sync.js";
import { radarSketch } from "./p5/radarSketch.js";
@ -94,8 +96,6 @@ import {
speedGraphContainer,
speedGraphPlaceholder,
toggleCloseUp,
updateFrame,
resetVisualization,
updateDebugOverlay,
timelineTooltip,
saveSessionBtn,
@ -915,14 +915,11 @@ document.addEventListener("keydown", (event) => {
if (key === "a") {
toggleDebugOverlay.click();
toggleDebug2Overlay.click();
if (isDebug1Visible && isDebug2Visible) {
radarInfoOverlay.classList.add("hidden");
videoInfoOverlay.classList.add("hidden");
return;
}
// Otherwise, make sure they are visible.
radarInfoOverlay.classList.remove("hidden");
videoInfoOverlay.classList.remove("hidden");
updatePersistentOverlays(videoPlayer.currentTime);
// The 'a' key is a shortcut to toggle all debug overlays on/off.
// The `updateDebugOverlay` and `updatePersistentOverlays` functions,
// which are called by the toggle's 'change' event listener,
// already handle the logic for showing/hiding the other overlays.
}
if (key === "m") {
if (collapsibleMenu.classList.contains("-translate-x-full")) {

101
steps/src/sync.js

@ -1,18 +1,33 @@
import { appState } from "./state.js";
import {
timelineSlider,
speedSlider,
offsetInput,
stopBtn,
playPauseBtn,
updateFrame,
updateDebugOverlay,
updatePersistentOverlays,
videoPlayer,
timelineSlider,
frameCounter,
toggleEgoSpeed,
egoSpeedDisplay,
canSpeedDisplay,
} from "./dom.js";
import { findRadarFrameIndexForTime } from "./utils.js";
import { throttledUpdateExplorer } from "./dataExplorer.js";
// --- [START] MOVED FROM DOM.JS ---
//----------------------RESET VISUALIZATION Function----------------------//
// Resets the visualization to its initial state.
export function resetVisualization() {
appState.isPlaying = false;
playPauseBtn.textContent = "Play";
const numFrames = appState.vizData.radarFrames.length;
timelineSlider.max = numFrames > 0 ? numFrames - 1 : 0;
updateFrame(0, true); // Update to the first frame and force video seek
}
// --- NEW Playback Control Functions ---
let seekDebounceTimer = null;
@ -56,6 +71,88 @@ export function forceResyncWithOffset() {
updateFrame(appState.currentFrame, true);
}
//----------------------UPDATE FRAME Function----------------------//
// Updates the UI to reflect the current radar frame and synchronizes video playback.
export function updateFrame(frame, forceVideoSeek) {
const startTime = performance.now(); //start emasuring timer of performance.
if (
!appState.vizData ||
frame < 0 ||
frame >= appState.vizData.radarFrames.length
)
// Exit if no visualization data or invalid frame.
return; // Exit if no visualization data or invalid frame
appState.currentFrame = frame;
timelineSlider.value = appState.currentFrame;
frameCounter.textContent = `Frame: ${appState.currentFrame + 1} / ${
appState.vizData.radarFrames.length
}`;
const frameData = appState.vizData.radarFrames[appState.currentFrame];
if (toggleEgoSpeed.checked && frameData) {
// Update ego speed display if enabled.
const egoVy_kmh = (frameData.egoVelocity[1] * 3.6).toFixed(1); // Convert m/s to km/h and format
egoSpeedDisplay.textContent = `Ego: ${egoVy_kmh} km/h`;
egoSpeedDisplay.classList.remove("hidden");
} else {
egoSpeedDisplay.classList.add("hidden"); // Hide ego speed display.
}
// --- ADD THIS NEW BLOCK ---
if (
frameData &&
frameData.canVehSpeed_kmph !== null &&
!isNaN(frameData.canVehSpeed_kmph)
) {
canSpeedDisplay.textContent = `CAN: ${frameData.canVehSpeed_kmph.toFixed(
1
)} km/h`;
canSpeedDisplay.classList.remove("hidden");
} else {
canSpeedDisplay.classList.add("hidden");
}
// --- END OF NEW BLOCK ---
let timeForUpdates = videoPlayer.currentTime; // NEW: Default to the video's current time
if (
forceVideoSeek &&
videoPlayer.src &&
videoPlayer.readyState > 1 &&
appState.videoStartDate &&
frameData
) {
const offsetMs = parseFloat(offsetInput.value) || 0;
const targetRadarTimeMs = frameData.timestampMs;
const targetVideoTimeSec = (targetRadarTimeMs - offsetMs) / 1000;
if (targetVideoTimeSec >= 0 && targetVideoTimeSec <= videoPlayer.duration) {
// Ensure target time is within video duration
if (Math.abs(videoPlayer.currentTime - targetVideoTimeSec) > 0.05) {
// Check for significant drift
videoPlayer.currentTime = targetVideoTimeSec; // Seek video if drift is significant
}
// MODIFIED: Use the calculated target time for our updates, not the stale videoPlayer.currentTime
timeForUpdates = targetVideoTimeSec; // Update time for subsequent UI updates
}
} // End of forceVideoSeek block
if (!appState.isPlaying) {
// MODIFIED: Use our new synchronized time variable
updatePersistentOverlays(timeForUpdates);
}
// --- End of fix ---
// --- START: Conditional Redraw Logic ---
// Only force a redraw from here if the animation loop is NOT running.
// When playing, the animationLoop is responsible for redrawing.
if (!appState.isPlaying && appState.p5_instance) appState.p5_instance.redraw();
if (!appState.isPlaying && appState.speedGraphInstance) appState.speedGraphInstance.redraw();
// --- NEW: Centralized Explorer Update ---
throttledUpdateExplorer();
// --- END: Centralized Explorer Update ---
const endTime = performance.now();
appState.lastFrameRenderTime = endTime - startTime; // <-- End timer and update state
}
// --- [END] MOVED FROM DOM.JS ---
export function stopPlayback() {
videoPlayer.pause();
if (appState.vizData) {

Loading…
Cancel
Save