Fix flyover button clickability and camera positioning
This commit is contained in:
@@ -9,10 +9,12 @@ const APP = () => {
|
||||
const mapRef = useRef(null);
|
||||
const startMarkerRef = useRef(null);
|
||||
const cityMarkersRef = useRef([]);
|
||||
const animationRef = useRef(null);
|
||||
const [selectedPoint, setSelectedPoint] = useState({ lat: 51.5074, lon: -0.1278 });
|
||||
const [direction, setDirection] = useState(45);
|
||||
const [lineOfSightData, setLineOfSightData] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [mapStyle, setMapStyle] = useState('light'); // 'light' or 'dark'
|
||||
const [tolerance, setTolerance] = useState(50);
|
||||
const [selectedCity, setSelectedCity] = useState(null);
|
||||
@@ -74,6 +76,7 @@ const APP = () => {
|
||||
});
|
||||
|
||||
return () => {
|
||||
if (animationRef.current) cancelAnimationFrame(animationRef.current);
|
||||
if (mapRef.current) mapRef.current.remove();
|
||||
};
|
||||
}, []); // Run only once
|
||||
@@ -108,6 +111,11 @@ const APP = () => {
|
||||
}, [isLocked]);
|
||||
|
||||
const handleStartAgain = () => {
|
||||
if (animationRef.current) {
|
||||
cancelAnimationFrame(animationRef.current);
|
||||
setIsPlaying(false);
|
||||
}
|
||||
|
||||
setIsLocked(false);
|
||||
setLineOfSightData(null);
|
||||
setSelectedCity(null);
|
||||
@@ -122,6 +130,14 @@ const APP = () => {
|
||||
if (mapRef.current.getLayer('preview-line')) {
|
||||
mapRef.current.setLayoutProperty('preview-line', 'visibility', 'visible');
|
||||
}
|
||||
|
||||
// Reset map pitch and zoom
|
||||
mapRef.current.flyTo({
|
||||
center: [selectedPoint.lon, selectedPoint.lat],
|
||||
zoom: 3,
|
||||
pitch: 0,
|
||||
bearing: 0
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -132,6 +148,60 @@ const APP = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const startFlyOver = () => {
|
||||
if (!lineOfSightData || !mapRef.current) return;
|
||||
|
||||
if (isPlaying) {
|
||||
if (animationRef.current) cancelAnimationFrame(animationRef.current);
|
||||
setIsPlaying(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPlaying(true);
|
||||
|
||||
const coordinates = lineOfSightData.line_coordinates.map(c => [c.lon, c.lat]);
|
||||
const route = turf.lineString(coordinates);
|
||||
const duration = 20000; // 20 seconds for the full flyover
|
||||
const startTime = performance.now();
|
||||
const routeDistance = turf.length(route);
|
||||
|
||||
function animate(currentTime) {
|
||||
if (!mapRef.current) return;
|
||||
|
||||
const elapsed = currentTime - startTime;
|
||||
const phase = Math.min(elapsed / duration, 1); // 0 to 1
|
||||
|
||||
// Stop when we reach the end
|
||||
if (phase >= 1) {
|
||||
setIsPlaying(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentDist = routeDistance * phase;
|
||||
|
||||
// Look 100km ahead, camera is at the current distance
|
||||
const target = turf.along(route, Math.min(currentDist + 100, routeDistance)).geometry.coordinates;
|
||||
const eye = turf.along(route, currentDist).geometry.coordinates;
|
||||
|
||||
const camera = mapRef.current.getFreeCameraOptions();
|
||||
|
||||
// Position camera 50,000m (50km) above the 'eye' point
|
||||
camera.position = maplibregl.MercatorCoordinate.fromLngLat(
|
||||
{ lng: eye[0], lat: eye[1] },
|
||||
50000
|
||||
);
|
||||
|
||||
// Look at the target point
|
||||
camera.lookAtPoint({ lng: target[0], lat: target[1] });
|
||||
|
||||
mapRef.current.setFreeCameraOptions(camera);
|
||||
|
||||
animationRef.current = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
animationRef.current = requestAnimationFrame(animate);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Update preview whenever point or direction changes
|
||||
if (mapRef.current && mapRef.current.isStyleLoaded()) {
|
||||
|
||||
@@ -126,16 +126,13 @@
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.disabled-controls input, .disabled-controls .action-btn {
|
||||
.disabled-controls input {
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.action-btn-secondary {
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.setting-row button {
|
||||
/* Allow action buttons and settings buttons to work even when locked */
|
||||
.action-btn, .action-btn-secondary, .setting-row button {
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user