diff --git a/app/src/App.css b/app/src/App.css index ca0fe3c41..df4dd4d7c 100644 --- a/app/src/App.css +++ b/app/src/App.css @@ -25,3 +25,24 @@ background-color: #e0e0e0; font-weight:700 } + +.ol-center-button { + padding: 1px; + display: flex; + justify-content: center; + align-items: center; + background-color: rgb(23 23 23); + border-radius: 6px; +} + +.ol-center-box { + position: absolute; + right: 12px; + bottom: 128px; + background-color: white; + border-radius: 6px; + display: flex; + flex-direction: column; + gap: 12px; + padding: 12px; +} \ No newline at end of file diff --git a/app/src/gui/components/map/center-control.tsx b/app/src/gui/components/map/center-control.tsx new file mode 100644 index 000000000..1fefb5ae1 --- /dev/null +++ b/app/src/gui/components/map/center-control.tsx @@ -0,0 +1,43 @@ +import {Control} from 'ol/control'; +import {Coordinate} from 'ol/coordinate'; +import {View} from 'ol'; +import {CreateDomIcon} from './dom-icon'; +import src from '../../../target.svg'; + +/** + * Creates a custom control button that centers the map view to a specified coordinate. + * + * @param {View} view - The map view instance to be controlled. + * @param {Coordinate} center - The coordinate to which the map view should be centered. + * @returns {Control} - The custom control instance. + */ +export const createCenterControl = ( + view: View, + center: Coordinate +): Control => { + const button = document.createElement('button'); + button.className = 'ol-center-button'; + + button.appendChild( + CreateDomIcon({ + src, + width: 24, + height: 24, + alt: 'Center map', + }) + ); + + const handleClick = () => { + view.setCenter(center); + }; + + button.addEventListener('click', handleClick); + + const element = document.createElement('div'); + element.className = 'ol-center-box'; + element.appendChild(button); + + return new Control({ + element: element, + }); +}; diff --git a/app/src/gui/components/map/dom-icon.tsx b/app/src/gui/components/map/dom-icon.tsx new file mode 100644 index 000000000..4961d4c91 --- /dev/null +++ b/app/src/gui/components/map/dom-icon.tsx @@ -0,0 +1,32 @@ +interface CenterControlIconProps { + src: string; + width: number; + height: number; + alt: string; +} + +/** + * Creates a DOM image element with the specified properties. + * + * @param {CenterControlIconProps} props - The properties for the image element. + * @param {string} props.src - The source URL of the image. + * @param {number} props.width - The width of the image in pixels. + * @param {number} props.height - The height of the image in pixels. + * @param {string} props.alt - The alternative text for the image. + * @returns {HTMLImageElement} - The created image element. + */ +export const CreateDomIcon = ({ + src, + width, + height, + alt, +}: CenterControlIconProps) => { + const img = document.createElement('img'); + + img.width = width; + img.height = height; + img.src = src; + img.alt = alt; + + return img; +}; diff --git a/app/src/gui/fields/maps/MapWrapper.tsx b/app/src/gui/fields/maps/MapWrapper.tsx index e08ca7747..e35ce531c 100644 --- a/app/src/gui/fields/maps/MapWrapper.tsx +++ b/app/src/gui/fields/maps/MapWrapper.tsx @@ -65,6 +65,7 @@ interface MapProps extends ButtonProps { import {AppBar, Dialog, IconButton, Toolbar, Typography} from '@mui/material'; import Feature from 'ol/Feature'; import {Geometry} from 'ol/geom'; +import {createCenterControl} from '../../components/map/center-control'; const styles = { mapContainer: { @@ -135,6 +136,8 @@ function MapWrapper(props: MapProps) { controls: [new Zoom()], }); + theMap.addControl(createCenterControl(theMap.getView(), center)); + theMap.getView().setCenter(center); return theMap; diff --git a/app/src/target.svg b/app/src/target.svg new file mode 100644 index 000000000..ea0c2ed43 --- /dev/null +++ b/app/src/target.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/purge.sh b/purge.sh old mode 100644 new mode 100755