From 38f0e9c66ed75a2f8c2953559bc5c23cb87ecc19 Mon Sep 17 00:00:00 2001 From: ratrun Date: Fri, 30 May 2025 11:46:08 +0200 Subject: [PATCH] Hide paths while pressing the "h" key or press a small icon next to the map attribution --- src/App.tsx | 10 ++++-- src/layers/UsePathsLayer.tsx | 8 ++--- src/map/Map.module.css | 24 +++++++++++++ src/map/MapComponent.tsx | 62 +++++++++++++++++++++++++++++++--- src/sidebar/visibility_off.svg | 1 + src/sidebar/visibility_on.svg | 1 + 6 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 src/sidebar/visibility_off.svg create mode 100644 src/sidebar/visibility_on.svg diff --git a/src/App.tsx b/src/App.tsx index f3c47eb7..a7e3b92c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -219,7 +219,10 @@ function LargeScreenLayout({ query, route, map, error, mapOptions, encodedValues
- +
@@ -243,7 +246,10 @@ function SmallScreenLayout({ query, route, map, error, mapOptions, encodedValues />
- +
diff --git a/src/layers/UsePathsLayer.tsx b/src/layers/UsePathsLayer.tsx index c502c48c..f6634362 100644 --- a/src/layers/UsePathsLayer.tsx +++ b/src/layers/UsePathsLayer.tsx @@ -35,14 +35,14 @@ export default function usePathsLayer(map: Map, paths: Path[], selectedPath: Pat }, [map, paths, selectedPath]) } -function removeCurrentPathLayers(map: Map) { +export function removeCurrentPathLayers(map: Map) { map.getLayers() .getArray() .filter(l => l.get(pathsLayerKey) || l.get(selectedPathLayerKey) || l.get(accessNetworkLayerKey)) .forEach(l => map.removeLayer(l)) } -function addUnselectedPathsLayer(map: Map, paths: Path[]) { +export function addUnselectedPathsLayer(map: Map, paths: Path[]) { const styleArray = [ new Style({ stroke: new Stroke({ @@ -118,7 +118,7 @@ function createBezierLineString(start: number[], end: number[]): LineString { return new LineString(bezierPoints) } -function addAccessNetworkLayer(map: Map, selectedPath: Path, queryPoints: QueryPoint[]) { +export function addAccessNetworkLayer(map: Map, selectedPath: Path, queryPoints: QueryPoint[]) { const style = new Style({ stroke: new Stroke({ color: 'rgba(143,183,241,0.9)', @@ -143,7 +143,7 @@ function addAccessNetworkLayer(map: Map, selectedPath: Path, queryPoints: QueryP map.addLayer(layer) } -function addSelectedPathsLayer(map: Map, selectedPath: Path) { +export function addSelectedPathsLayer(map: Map, selectedPath: Path) { const styleArray = [ new Style({ stroke: new Stroke({ diff --git a/src/map/Map.module.css b/src/map/Map.module.css index 074f894e..b32030eb 100644 --- a/src/map/Map.module.css +++ b/src/map/Map.module.css @@ -41,3 +41,27 @@ .customAttribution button { display: none; } + +.topBar { + position: absolute; + left: 0; + bottom: -0.3rem; + width: 100%; + z-index: 1; + padding: 1px 180px; +} + +.hidePathsButton { + display: inline-block; + background: none; + border: none; + font-size: 13px; + padding: 8px 16px; + margin: 0; +} + +@media (max-width: 44rem) { + .smallScreenRoutingResultVisible .topBar { + bottom: 8.25rem; + } +} diff --git a/src/map/MapComponent.tsx b/src/map/MapComponent.tsx index ac2d39b3..6f0c5e95 100644 --- a/src/map/MapComponent.tsx +++ b/src/map/MapComponent.tsx @@ -1,24 +1,78 @@ import 'ol/ol.css' import styles from '@/map/Map.module.css' -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import { Map } from 'ol' import { Bbox } from '@/api/graphhopper' import Dispatcher from '@/stores/Dispatcher' import { ErrorAction } from '@/actions/Actions' import { tr } from '@/translation/Translation' import { Coordinate, getBBoxFromCoord } from '@/utils' +import { addUnselectedPathsLayer, addSelectedPathsLayer, addAccessNetworkLayer, removeCurrentPathLayers } from '@/layers/UsePathsLayer' +import { Path } from '@/api/graphhopper' +import { QueryPoint } from '@/stores/QueryStore' +import VisibilityOnIcon from '@/sidebar/visibility_on.svg' +import VisibilityOffIcon from '@/sidebar/visibility_off.svg' type MapComponentProps = { - map: Map + map: Map, + paths: Path[], + selectedPath: Path, + queryPoints: QueryPoint[] } /** A small react component that simply attaches our map instance to a div to show the map **/ -export default function ({ map }: MapComponentProps) { +export default function ({ + map, paths, selectedPath, queryPoints, smallScreenRoutingResultVisible +}: MapComponentProps & { smallScreenRoutingResultVisible?: boolean }) { const mapElement = useRef(null) useEffect(() => { map.setTarget(mapElement.current!) }, [map]) - return
+ const [showPaths, setShowPaths] = useState(true) + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'h') setShowPaths(false) + } + const handleKeyUp = (e: KeyboardEvent) => { + if (e.key === 'h') setShowPaths(true) + } + window.addEventListener('keydown', handleKeyDown) + window.addEventListener('keyup', handleKeyUp) + return () => { + window.removeEventListener('keydown', handleKeyDown) + window.removeEventListener('keyup', handleKeyUp) + } + }, []) + useEffect(() => { + removeCurrentPathLayers(map) + if (showPaths) { + addUnselectedPathsLayer(map, paths.filter(p => p != selectedPath)) + addSelectedPathsLayer(map, selectedPath) + addAccessNetworkLayer(map, selectedPath, queryPoints) + } + return () => { + removeCurrentPathLayers(map) + } + }, [map, paths, selectedPath, showPaths]) + return ( +
+
+ +
+
+ ) } export function onCurrentLocationSelected( diff --git a/src/sidebar/visibility_off.svg b/src/sidebar/visibility_off.svg new file mode 100644 index 00000000..d4a6ec45 --- /dev/null +++ b/src/sidebar/visibility_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/sidebar/visibility_on.svg b/src/sidebar/visibility_on.svg new file mode 100644 index 00000000..d1366578 --- /dev/null +++ b/src/sidebar/visibility_on.svg @@ -0,0 +1 @@ + \ No newline at end of file