X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=resources%2Fjs%2Fcomponents%2Fmap%2FOpenSeadragon.js;h=36ddec1ce4c0685ba471ce101b4913c04f503cf3;hb=24489254a5d05efd6fe7dceb2cffe5fdb49ab7b7;hp=f8543189e18c3b71ea4344be4e3ba0634d58fbc1;hpb=18424fc6de2fc902ee2b2d3143955081263adff4;p=alttp.git diff --git a/resources/js/components/map/OpenSeadragon.js b/resources/js/components/map/OpenSeadragon.js index f854318..36ddec1 100644 --- a/resources/js/components/map/OpenSeadragon.js +++ b/resources/js/components/map/OpenSeadragon.js @@ -1,14 +1,55 @@ +import axios from 'axios'; import OpenSeadragon from 'openseadragon'; import PropTypes from 'prop-types'; import React from 'react'; +import { useNavigate, useParams } from 'react-router'; +import { createSearchParams, useSearchParams } from 'react-router-dom'; export const Context = React.createContext({}); export const useOpenSeadragon = () => React.useContext(Context); export const Provider = React.forwardRef(({ children }, ref) => { + const { activeMap } = useParams(); + const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + const [pins, setPins] = React.useState([]); const [viewer, setViewer] = React.useState(null); + const storePosition = React.useCallback(() => { + if (!viewer || !viewer.viewport) return; + const center = viewer.viewport.getCenter(); + const zoom = viewer.viewport.getZoom(); + setSearchParams({ x: center.x, y: center.y, z: zoom }, { replace: true }); + }, [setSearchParams, viewer]); + + const setActiveMap = React.useCallback(map => { + if (viewer && viewer.viewport) { + const center = viewer.viewport.getCenter(); + const zoom = viewer.viewport.getZoom(); + const params = { x: center.x, y: center.y, z: zoom }; + navigate( + { pathname: `../${map}`, search: `?${createSearchParams(params)}` }, + { replace: true }, + ); + } else { + navigate(`../${map}`, { replace: true }); + } + }, [navigate, viewer]); + + React.useEffect(() => { + if (!viewer || !viewer.viewport) return; + if (searchParams.has('x') && searchParams.has('y')) { + viewer.viewport.panTo(new OpenSeadragon.Point( + parseFloat(searchParams.get('x')), + parseFloat(searchParams.get('y')), + )); + } + if (searchParams.has('z')) { + viewer.viewport.zoomTo(parseFloat(searchParams.get('z'))); + } + }, [searchParams, viewer]); + React.useEffect(() => { if (!ref.current) return; @@ -56,16 +97,66 @@ export const Provider = React.forwardRef(({ children }, ref) => { maxLevel: 14, tilesUrl: '/media/alttp/map/uw_files/', fileFormat: 'png', + }), new OpenSeadragon.DziTileSource({ + width: 16384, + height: 3072, + tileSize: 256, + tileOverlap: 0, + minLevel: 8, + maxLevel: 14, + tilesUrl: '/media/alttp/map/uw2_files/', + fileFormat: 'png', }), ], }); + v.addHandler('canvas-nonprimary-press', e => { + if (e.button === 3) { + navigate(-1); + } else if (e.button === 4) { + navigate(1); + } + }); setViewer(v); return () => { v.destroy(); }; }, [ref.current]); - return + React.useEffect(() => { + if (!viewer) return; + switch (activeMap) { + case 'lw': + viewer.goToPage(0); + break; + case 'dw': + viewer.goToPage(1); + break; + case 'sp': + viewer.goToPage(2); + break; + case 'uw': + viewer.goToPage(3); + break; + case 'uw2': + viewer.goToPage(4); + break; + } + const controller = new AbortController(); + axios.get(`/api/markers/${activeMap}`, { + signal: controller.signal, + }).then(response => { + setPins(response.data || []); + }).catch(e => { + if (!axios.isCancel(e)) { + console.error(e); + } + }); + return () => { + controller.abort(); + }; + }, [activeMap, viewer]); + + return {children} ; });