From 18424fc6de2fc902ee2b2d3143955081263adff4 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 1 Feb 2023 15:48:26 +0100 Subject: [PATCH] add plain maps --- package-lock.json | 14 +++ package.json | 1 + resources/js/components/App.js | 2 + resources/js/components/map/Buttons.js | 47 ++++++++ resources/js/components/map/OpenSeadragon.js | 79 ++++++++++++++ resources/js/components/map/Viewer.js | 109 +++++++++++++++++++ resources/js/components/pages/Map.js | 23 ++++ resources/js/i18n/de.js | 11 ++ resources/js/i18n/en.js | 11 ++ webpack.mix.js | 1 + 10 files changed, 298 insertions(+) create mode 100644 resources/js/components/map/Buttons.js create mode 100644 resources/js/components/map/OpenSeadragon.js create mode 100644 resources/js/components/map/Viewer.js create mode 100644 resources/js/components/pages/Map.js diff --git a/package-lock.json b/package-lock.json index f5f22c9..6bc7914 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "localforage": "^1.10.0", "moment": "^2.29.1", "numeral": "^2.0.6", + "openseadragon": "^4.0.0", "pusher-js": "^7.0.6", "qs": "^6.10.3", "react-bootstrap": "^2.2.0", @@ -8280,6 +8281,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openseadragon": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/openseadragon/-/openseadragon-4.0.0.tgz", + "integrity": "sha512-HsjSgqiiPwLkW5576GxDJ7Rax96iLUET8fnTsJvu7uYYkd+qzen3bflxHyph0OVVgZBKP9SpGH1nPdU4Mz0Z2A==", + "funding": { + "url": "https://opencollective.com/openseadragon" + } + }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -18393,6 +18402,11 @@ "is-wsl": "^2.2.0" } }, + "openseadragon": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/openseadragon/-/openseadragon-4.0.0.tgz", + "integrity": "sha512-HsjSgqiiPwLkW5576GxDJ7Rax96iLUET8fnTsJvu7uYYkd+qzen3bflxHyph0OVVgZBKP9SpGH1nPdU4Mz0Z2A==" + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", diff --git a/package.json b/package.json index 144f3dd..4f7a3a6 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "localforage": "^1.10.0", "moment": "^2.29.1", "numeral": "^2.0.6", + "openseadragon": "^4.0.0", "pusher-js": "^7.0.6", "qs": "^6.10.3", "react-bootstrap": "^2.2.0", diff --git a/resources/js/components/App.js b/resources/js/components/App.js index fe8ff25..d84474c 100644 --- a/resources/js/components/App.js +++ b/resources/js/components/App.js @@ -6,6 +6,7 @@ import Footer from './common/Footer'; import Header from './common/Header'; import AlttpSeed from './pages/AlttpSeed'; import Front from './pages/Front'; +import Map from './pages/Map'; import Technique from './pages/Technique'; import Techniques from './pages/Techniques'; import Tournament from './pages/Tournament'; @@ -59,6 +60,7 @@ const App = () => {
} /> + } /> } diff --git a/resources/js/components/map/Buttons.js b/resources/js/components/map/Buttons.js new file mode 100644 index 0000000..b43fc0e --- /dev/null +++ b/resources/js/components/map/Buttons.js @@ -0,0 +1,47 @@ +import React from 'react'; +import { Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { useOpenSeadragon } from './OpenSeadragon'; + +const Buttons = () => { + const { viewer } = useOpenSeadragon(); + const { t } = useTranslation(); + + const goToPage = React.useCallback((p) => { + if (viewer) viewer.goToPage(p); + }, [viewer]); + + return
+ + + + +
; +}; + +export default Buttons; diff --git a/resources/js/components/map/OpenSeadragon.js b/resources/js/components/map/OpenSeadragon.js new file mode 100644 index 0000000..f854318 --- /dev/null +++ b/resources/js/components/map/OpenSeadragon.js @@ -0,0 +1,79 @@ +import OpenSeadragon from 'openseadragon'; +import PropTypes from 'prop-types'; +import React from 'react'; + +export const Context = React.createContext({}); + +export const useOpenSeadragon = () => React.useContext(Context); + +export const Provider = React.forwardRef(({ children }, ref) => { + const [viewer, setViewer] = React.useState(null); + + React.useEffect(() => { + if (!ref.current) return; + + const v = OpenSeadragon({ + element: ref.current, + preserveViewport: true, + sequenceMode: true, + showNavigator: true, + showNavigationControl: false, + showSequenceControl: false, + tileSources: [ + new OpenSeadragon.DziTileSource({ + width: 8192, + height: 8192, + tileSize: 256, + tileOverlap: 0, + minLevel: 8, + maxLevel: 13, + tilesUrl: '/media/alttp/map/lw_files/', + fileFormat: 'png', + }), new OpenSeadragon.DziTileSource({ + width: 8192, + height: 8192, + tileSize: 256, + tileOverlap: 0, + minLevel: 8, + maxLevel: 13, + tilesUrl: '/media/alttp/map/dw_files/', + fileFormat: 'png', + }), new OpenSeadragon.DziTileSource({ + width: 8192, + height: 4096, + tileSize: 256, + tileOverlap: 0, + minLevel: 8, + maxLevel: 13, + tilesUrl: '/media/alttp/map/sp_files/', + fileFormat: 'png', + }), new OpenSeadragon.DziTileSource({ + width: 16384, + height: 16384, + tileSize: 256, + tileOverlap: 0, + minLevel: 8, + maxLevel: 14, + tilesUrl: '/media/alttp/map/uw_files/', + fileFormat: 'png', + }), + ], + }); + setViewer(v); + return () => { + v.destroy(); + }; + }, [ref.current]); + + return + {children} + ; +}); + +Provider.displayName = 'OpenSeadragonProvider'; + +Provider.propTypes = { + children: PropTypes.node, +}; + +export default Provider; diff --git a/resources/js/components/map/Viewer.js b/resources/js/components/map/Viewer.js new file mode 100644 index 0000000..473c179 --- /dev/null +++ b/resources/js/components/map/Viewer.js @@ -0,0 +1,109 @@ +import OpenSeadragon from 'openseadragon'; +import React from 'react'; +import { Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +const Viewer = () => { + const [viewer, setViewer] = React.useState(null); + + const container = React.useRef(); + const { t } = useTranslation(); + + React.useEffect(() => { + if (!container.current) return; + + const v = OpenSeadragon({ + element: container.current, + preserveViewport: true, + sequenceMode: true, + showNavigator: true, + showNavigationControl: false, + showSequenceControl: false, + //tileSources: [ + // new OpenSeadragon.DziTileSource({ + // width: 8192, + // height: 8192, + // tileSize: 256, + // tileOverlap: 0, + // minLevel: 8, + // maxLevel: 13, + // tilesUrl: '/media/alttp/map/lw_files/', + // fileFormat: 'png', + // }), new OpenSeadragon.DziTileSource({ + // width: 8192, + // height: 8192, + // tileSize: 256, + // tileOverlap: 0, + // minLevel: 8, + // maxLevel: 13, + // tilesUrl: '/media/alttp/map/dw_files/', + // fileFormat: 'png', + // }), new OpenSeadragon.DziTileSource({ + // width: 8192, + // height: 8192, + // tileSize: 256, + // tileOverlap: 0, + // minLevel: 8, + // maxLevel: 13, + // tilesUrl: '/media/alttp/map/sp_files/', + // fileFormat: 'png', + // }), new OpenSeadragon.DziTileSource({ + // width: 16384, + // height: 16384, + // tileSize: 256, + // tileOverlap: 0, + // minLevel: 8, + // maxLevel: 14, + // tilesUrl: '/media/alttp/map/uw_files/', + // fileFormat: 'png', + // }), + //], + }); + setViewer(v); + return () => { + v.destroy(); + }; + }, [container.current]); + + const goToPage = React.useCallback((p) => { + if (viewer) viewer.goToPage(p); + }, [viewer]); + + return <> +
+
+ + + + +
+
+
+ ; +}; + +export default Viewer; diff --git a/resources/js/components/pages/Map.js b/resources/js/components/pages/Map.js new file mode 100644 index 0000000..50a28fb --- /dev/null +++ b/resources/js/components/pages/Map.js @@ -0,0 +1,23 @@ +import React from 'react'; +import { Container } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import Buttons from '../map/Buttons'; +import OpenSeadragon from '../map/OpenSeadragon'; + +const Map = () => { + const container = React.useRef(); + const { t } = useTranslation(); + + return + +
+

{t('map.heading')}

+ +
+
+ + ; +}; + +export default Map; diff --git a/resources/js/i18n/de.js b/resources/js/i18n/de.js index 0812fd4..f4b73e5 100644 --- a/resources/js/i18n/de.js +++ b/resources/js/i18n/de.js @@ -374,6 +374,17 @@ export default { somaria: 'Cane of Somaria', }, }, + map: { + dwLong: 'Dark World', + dwShort: 'DW', + heading: 'Karte', + lwLong: 'Light World', + lwShort: 'LW', + spLong: 'Spezielle Gebiete', + spShort: 'SP', + uwLong: 'Underworld', + uwShort: 'UW', + }, modes: { heading: 'Modi', }, diff --git a/resources/js/i18n/en.js b/resources/js/i18n/en.js index 030b023..6498b85 100644 --- a/resources/js/i18n/en.js +++ b/resources/js/i18n/en.js @@ -374,6 +374,17 @@ export default { somaria: 'Cane of Somaria', }, }, + map: { + dwLong: 'Dark World', + dwShort: 'DW', + heading: 'Map', + lwLong: 'Light World', + lwShort: 'LW', + spLong: 'Special Areas', + spShort: 'SP', + uwLong: 'Underworld', + uwShort: 'UW', + }, modes: { heading: 'Modes', }, diff --git a/webpack.mix.js b/webpack.mix.js index 0e8f447..714cba7 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -67,6 +67,7 @@ mix.js('resources/js/app.js', 'public/js') 'nanoclone', 'object-assign', 'object-inspect', + 'openseadragon', 'performance-now', 'process', 'prop-types', -- 2.39.2