import React, { useState, useEffect, useRef, useCallback } from "react"; // @ts-ignore import mapboxgl from '!mapbox-gl'; // eslint-disable-line import/no-webpack-loader-syntax import { MAPBOX_ACCESS_TOKEN, IMAGE_COORDINATES, IMAGES_BASE_URL } from "./config"; import "mapbox-gl/dist/mapbox-gl.css"; interface MapProps { slider: number, images: string[], } export function Map({ slider, images }: MapProps) { const mapContainer = useRef(null); const map = useRef(null); const [lng, setLng] = useState(35); const [lat, setLat] = useState(31.9); const [zoom, setZoom] = useState(6.3); const prevImages = useRef(images).current; const prevSlider = useRef(slider).current; const updateLayers = useCallback(() => { if (!map.current || !map.current.isStyleLoaded()) return; // remove old layers prevImages.forEach((img) => { if (!images.includes(img)) { map.current.removeLayer(`layer-${img}`); map.current.removeSource(`source-${img}`); } }); // add new layers images.forEach((img, i) => { if (!prevImages.includes(img)) { map.current.addSource(`source-${img}`, { type: "image", url: `${IMAGES_BASE_URL}/${img}`, coordinates: IMAGE_COORDINATES }); map.current.addLayer({ id: `layer-${img}`, source: `source-${img}`, type: "raster", paint: { "raster-opacity": 0.5, "raster-opacity-transition": { duration: 0 } } }); } }); }, [prevImages, images]); useEffect(() => { if (map.current) return; map.current = new mapboxgl.Map({ accessToken: MAPBOX_ACCESS_TOKEN, container: mapContainer.current, style: "mapbox://styles/mapbox/dark-v9", center: [lng, lat], zoom: zoom, minZoom: 5, maxZoom: 10, hash: false, }); map.current.on("style.load", () => { updateLayers(); }); }); useEffect(() => { if (!map.current || !map.current.isStyleLoaded()) return; map.current.on('move', () => { setLng(map.current.getCenter().lng.toFixed(4)); setLat(map.current.getCenter().lat.toFixed(4)); setZoom(map.current.getZoom().toFixed(2)); }); }); useEffect(() => { updateLayers(); }, [updateLayers, prevImages, images]); useEffect(() => { if (!map.current || !map.current.isStyleLoaded()) return; map.current.setPaintProperty(`layer-${images[prevSlider]}`, "raster-opacity", 0); map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0.85); }, [prevSlider, slider, images]); return (
); }