Browse Source

feat(file-loading): Improve FPS counter accuracy and video retention Enhance FPS counter stability by implementing a warmup period and explicit reset of appState.fps`, preventing erroneous spikes after new file loads.

Resolve infinite p5.js auto-draw loop during file processing by ensuring comprehensive UI cleanup and correct p5 instance lifecycle management (`redraw` instead of `lo`).

Introduce conditional video retention in `resetUIForNewLoad`, allowing the loaded video to persist when only new JSON data is supplied.
refactor/sync-centralize
RUSHIL AMBARISH KADU 6 months ago
parent
commit
db3e7495c0
  1. 31
      steps/src/dom.js
  2. 11
      steps/src/fileLoader.js
  3. 27
      steps/src/p5/radarSketch.js

31
steps/src/dom.js

@ -104,21 +104,36 @@ export const explorerBtn = document.getElementById("explorer-btn");
//----------------------Reset UI for New file Load----------------------//
// Resets the UI to make sure everything is clean before new files load.
export function resetUIForNewLoad() {
console.log("Resetting UI for new file load.");
// @param {boolean} isNewVideo - If true, the video player will be reset. If false, existing video is preserved.
export function resetUIForNewLoad(isNewVideo = true) {
console.log(`Resetting UI for new file load. New Video: ${isNewVideo}`);
// Hide feature toggles
featureToggles.classList.add("hidden");
// Show placeholders
// Reset the FPS counter state to prevent incorrect calculations on reload
appState.fps = 0;
// --- Conditional Video Reset ---
if (isNewVideo || !videoPlayer.src) {
// Reset video UI: Show placeholder, hide player, clear source
videoPlaceholder.classList.remove('hidden');
videoPlayer.classList.add('hidden');
videoPlayer.src = ''; // Clear the video source
videoInfoOverlay.classList.add('hidden');
} else {
// Preserve video UI: Ensure player is visible, placeholder hidden
videoPlaceholder.classList.add('hidden');
videoPlayer.classList.remove('hidden');
// Do NOT clear videoPlayer.src
videoInfoOverlay.classList.remove('hidden');
}
// Show canvas placeholder (will be hidden later if data loads)
canvasPlaceholder.style.display = 'flex';
videoPlaceholder.classList.remove('hidden');
// Hide video player and overlays
videoPlayer.classList.add('hidden');
videoPlayer.src = ''; // Clear the video source
// Always hide radar overlay initially
radarInfoOverlay.classList.add('hidden');
videoInfoOverlay.classList.add('hidden');
// Remove the p5 sketches completely
if (appState.p5_instance) {

11
steps/src/fileLoader.js

@ -30,6 +30,7 @@ import {
speedSlider,
updatePersistentOverlays,
updateDebugOverlay,
resetUIForNewLoad,
} from "./dom.js";
/**
@ -58,6 +59,11 @@ export function handleFiles(files, fromCache = false) {
}
async function processFilePipeline(jsonFile, videoFile, fromCache) {
// 0. Reset the UI to a clean state before processing anything.
// Pass 'true' if a new video is present, 'false' if we should try to keep the old one.
const isNewVideo = !!videoFile;
resetUIForNewLoad(isNewVideo);
// 1. Show the unified loading modal.
showLoadingModal("Processing files...");
@ -298,8 +304,9 @@ function finalizeSetup() {
if (!appState.p5_instance) {
appState.p5_instance = new p5(radarSketch);
} else {
// If it existed, ensure it's looping/active
appState.p5_instance.loop();
// If it existed, ensure it's up to date.
// CRITICAL: Do NOT call .loop(). The app uses a custom animationLoop in sync.js.
appState.p5_instance.redraw();
}
if (!appState.zoomSketchInstance) {

27
steps/src/p5/radarSketch.js

@ -48,6 +48,7 @@ export const radarSketch = function (p) {
// --- START: FPS Calculation Variables ---
let lastFrameTime = 0;
let framesDrawn = 0;
// --- END: FPS Calculation Variables ---
// Helper function to allow other sketches to access the static background
@ -126,6 +127,10 @@ export const radarSketch = function (p) {
p.drawTrackLegendToBuffer(); // Call the new function to draw the legend
drawStaticRegionsToBuffer(p, staticBackgroundBuffer, plotScales);
// Reset FPS state to prevent stale values from previous sessions
appState.fps = 0;
p.noLoop();
// Disable continuous looping, redraw will be called manually
};
@ -136,18 +141,28 @@ export const radarSketch = function (p) {
}
// --- START: FPS Calculation & Display ---
framesDrawn++;
const currentTime = p.millis();
if (lastFrameTime > 0) {
// Skip FPS calculation during the first few frames to avoid initialization spikes.
// This prevents the "300+ FPS" bug caused by the race between auto-draw and first redraw.
if (framesDrawn < 10) {
lastFrameTime = currentTime;
} else {
const delta = currentTime - lastFrameTime;
if (delta > 0) {
const currentFps = 1000 / delta;
// Use exponential moving average for smoothing
const smoothingFactor = 0.95;
appState.fps =
appState.fps * smoothingFactor + currentFps * (1 - smoothingFactor);
// On the first valid calculation, snap to the current FPS to avoid slow ramp-up.
// Otherwise, use exponential moving average for smoothing.
if (framesDrawn === 10 || appState.fps === 0) {
appState.fps = currentFps;
} else {
const smoothingFactor = 0.95;
appState.fps = appState.fps * smoothingFactor + currentFps * (1 - smoothingFactor);
}
}
lastFrameTime = currentTime;
}
lastFrameTime = currentTime;
// --- END: FPS Calculation & Display ---
// Set background color based on current theme (dark/light)

Loading…
Cancel
Save