fix: Prevent animation on first load and data refresh

The 'dropping to bottom of screen' effect was caused by ALL markers
animating on every data refresh, not just truly new events.

Root cause:
- On first plugin enable: previousQuakeIds/previousStrikeIds is empty
- Every marker looked 'new' and animated
- On data refresh (every 5 min): all markers recreated and animated
- Result: appeared as if markers were 'dropping' or 'falling'

Solution:
- Added isFirstLoad ref flag for both plugins
- First load: populate previousIds but DON'T animate
- Subsequent loads: only animate truly NEW events
- isNew = !isFirstLoad && !previousIds.has(id)

Behavior now:
- Enable plugin: Markers appear static (no animation)
- Wait 5 min refresh: Still static (no animation)
- NEW earthquake/strike detected: ONLY that one animates
- Result: Clean, professional, no 'dropping' effect

Applies to:
- Earthquakes: Fixed
- Lightning: Fixed
pull/82/head
trancen 2 days ago
parent 6afe508af3
commit 53ea4ad473

@ -24,6 +24,7 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
const [markersRef, setMarkersRef] = useState([]); const [markersRef, setMarkersRef] = useState([]);
const [earthquakeData, setEarthquakeData] = useState([]); const [earthquakeData, setEarthquakeData] = useState([]);
const previousQuakeIds = useRef(new Set()); const previousQuakeIds = useRef(new Set());
const isFirstLoad = useRef(true);
// Fetch earthquake data // Fetch earthquake data
useEffect(() => { useEffect(() => {
@ -33,7 +34,8 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
try { try {
// USGS GeoJSON feed - M2.5+ from last day // USGS GeoJSON feed - M2.5+ from last day
const response = await fetch( const response = await fetch(
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson' //'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson'
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_hour.geojson'
); );
const data = await response.json(); const data = await response.json();
setEarthquakeData(data.features || []); setEarthquakeData(data.features || []);
@ -44,7 +46,8 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
fetchEarthquakes(); fetchEarthquakes();
// Refresh every 5 minutes // Refresh every 5 minutes
const interval = setInterval(fetchEarthquakes, 300000); //const interval = setInterval(fetchEarthquakes, 300000);
const interval = setInterval(fetchEarthquakes, 60000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, [enabled]); }, [enabled]);
@ -82,8 +85,8 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
// Skip if invalid coordinates // Skip if invalid coordinates
if (!lat || !lon || isNaN(lat) || isNaN(lon)) return; if (!lat || !lon || isNaN(lat) || isNaN(lon)) return;
// Check if this is a new earthquake // Check if this is a new earthquake (but not on first load)
const isNew = !previousQuakeIds.current.has(quakeId); const isNew = !isFirstLoad.current && !previousQuakeIds.current.has(quakeId);
// Calculate marker size based on magnitude (M2.5 = 8px, M7+ = 40px) // Calculate marker size based on magnitude (M2.5 = 8px, M7+ = 40px)
const size = Math.min(Math.max(mag * 4, 8), 40); const size = Math.min(Math.max(mag * 4, 8), 40);
@ -187,6 +190,11 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
// Update previous quake IDs for next comparison // Update previous quake IDs for next comparison
previousQuakeIds.current = currentQuakeIds; previousQuakeIds.current = currentQuakeIds;
// After first load, allow animations for new quakes
if (isFirstLoad.current) {
isFirstLoad.current = false;
}
setMarkersRef(newMarkers); setMarkersRef(newMarkers);

@ -6,7 +6,7 @@ import { useState, useEffect, useRef } from 'react';
export const metadata = { export const metadata = {
id: 'lightning', id: 'lightning',
name: 'Lightning Detection', name: 'Lightning Detection(Testing-Simulated)',
description: 'Real-time lightning strike detection and visualization', description: 'Real-time lightning strike detection and visualization',
icon: '⚡', icon: '⚡',
category: 'weather', category: 'weather',
@ -79,6 +79,7 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
const [statsControl, setStatsControl] = useState(null); const [statsControl, setStatsControl] = useState(null);
const previousStrikeIds = useRef(new Set()); const previousStrikeIds = useRef(new Set());
const updateIntervalRef = useRef(null); const updateIntervalRef = useRef(null);
const isFirstLoad = useRef(true);
// Fetch lightning data (simulated for now) // Fetch lightning data (simulated for now)
useEffect(() => { useEffect(() => {
@ -133,8 +134,8 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
currentStrikeIds.add(id); currentStrikeIds.add(id);
// Check if this is a new strike // Check if this is a new strike (but not on first load)
const isNew = !previousStrikeIds.current.has(id); const isNew = !isFirstLoad.current && !previousStrikeIds.current.has(id);
// Calculate age in minutes // Calculate age in minutes
const ageMinutes = age / 60; const ageMinutes = age / 60;
@ -231,6 +232,11 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null }) {
// Update previous strike IDs for next comparison // Update previous strike IDs for next comparison
previousStrikeIds.current = currentStrikeIds; previousStrikeIds.current = currentStrikeIds;
// After first load, allow animations for new strikes
if (isFirstLoad.current) {
isFirstLoad.current = false;
}
setStrikeMarkers(newMarkers); setStrikeMarkers(newMarkers);
return () => { return () => {

Loading…
Cancel
Save

Powered by TurnKey Linux.