Play/pause flyover
This commit is contained in:
+43
-12
@@ -372,6 +372,9 @@ const APP = () => {
|
||||
setIsPlaying(false);
|
||||
setFlightSpeed(1.0);
|
||||
}
|
||||
flightProgressRef.current = 0;
|
||||
setCurrentCityIndex(-1);
|
||||
currentCityIndexRef.current = -1;
|
||||
if (popupRef.current) {
|
||||
popupRef.current.remove();
|
||||
popupRef.current = null;
|
||||
@@ -458,14 +461,11 @@ const APP = () => {
|
||||
if (animationRef.current) cancelAnimationFrame(animationRef.current);
|
||||
setIsPlaying(false);
|
||||
setFlightSpeed(1.0);
|
||||
setCurrentCityIndex(-1);
|
||||
currentCityIndexRef.current = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPlaying(true);
|
||||
setCurrentCityIndex(-1);
|
||||
currentCityIndexRef.current = -1;
|
||||
// Don't reset currentCityIndex here, so it resumes correctly
|
||||
if (popupRef.current) popupRef.current.remove();
|
||||
|
||||
const coordinates = lineOfSightData.line_coordinates.map(c => [c.lon, c.lat]);
|
||||
@@ -474,7 +474,7 @@ const APP = () => {
|
||||
|
||||
let lastFetchedDist = flightProgressRef.current;
|
||||
let currentProgress = flightProgressRef.current;
|
||||
flightProgressRef.current = 0;
|
||||
// Removed: flightProgressRef.current = 0; - We keep the ref to resume.
|
||||
let lastTimestamp = performance.now();
|
||||
let currentSpeedMultiplier = 1.0;
|
||||
let frameCount = 0;
|
||||
@@ -583,6 +583,7 @@ const APP = () => {
|
||||
}
|
||||
}
|
||||
|
||||
flightProgressRef.current = currentProgress;
|
||||
animationRef.current = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
@@ -749,6 +750,10 @@ const APP = () => {
|
||||
console.error('Error fetching line of sight:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
// Reset flight progress for a new line calculation
|
||||
flightProgressRef.current = 0;
|
||||
setCurrentCityIndex(-1);
|
||||
currentCityIndexRef.current = -1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -841,13 +846,39 @@ const APP = () => {
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
className="action-btn"
|
||||
onClick={startFlyOver}
|
||||
style={{ backgroundColor: isPlaying ? '#e74c3c' : '#3498db' }}
|
||||
>
|
||||
{isPlaying ? `⏹ Stop Flight (${flightSpeed.toFixed(1)}x)` : '✈️ Fly Over Route'}
|
||||
</button>
|
||||
<div className="fly-controls">
|
||||
<button
|
||||
className={`fly-button ${isPlaying ? 'pause' : 'play'}`}
|
||||
onClick={startFlyOver}
|
||||
disabled={!lineOfSightData}
|
||||
>
|
||||
{isPlaying ? `Pause Flyover (${flightSpeed.toFixed(1)}x)` : (flightProgressRef.current > 0 ? 'Resume Flyover' : 'Start Flyover')}
|
||||
</button>
|
||||
<button
|
||||
className="reset-flight-btn"
|
||||
onClick={() => {
|
||||
cancelAnimationFrame(animationRef.current);
|
||||
setIsPlaying(false);
|
||||
setFlightSpeed(1.0);
|
||||
flightProgressRef.current = 0;
|
||||
setCurrentCityIndex(-1);
|
||||
currentCityIndexRef.current = -1;
|
||||
// Move camera back to start
|
||||
if (mapRef.current) {
|
||||
mapRef.current.flyTo({
|
||||
center: [selectedPoint.lon, selectedPoint.lat],
|
||||
zoom: 4,
|
||||
pitch: 0,
|
||||
bearing: 0
|
||||
});
|
||||
}
|
||||
}}
|
||||
disabled={!lineOfSightData || (flightProgressRef.current === 0 && !isPlaying)}
|
||||
title="Reset flight to beginning"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
<button className="action-btn-secondary" onClick={handleStartAgain}>
|
||||
🔄 Start Again
|
||||
</button>
|
||||
|
||||
@@ -463,3 +463,62 @@
|
||||
font-size: 13px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.fly-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.fly-button {
|
||||
flex: 3;
|
||||
padding: 12px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.fly-button.play {
|
||||
background: #3498db;
|
||||
}
|
||||
|
||||
.fly-button.play:hover {
|
||||
background: #2980b9;
|
||||
}
|
||||
|
||||
.fly-button.pause {
|
||||
background: #e74c3c;
|
||||
}
|
||||
|
||||
.fly-button.pause:hover {
|
||||
background: #c0392b;
|
||||
}
|
||||
|
||||
.reset-flight-btn {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
background: #95a5a6;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.reset-flight-btn:hover:not(:disabled) {
|
||||
background: #7f8c8d;
|
||||
}
|
||||
|
||||
.reset-flight-btn:disabled {
|
||||
background: #ecf0f1;
|
||||
color: #bdc3c7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user