Skip to content
Snippets Groups Projects
Commit a6550f08 authored by Moritz Stueckler's avatar Moritz Stueckler
Browse files

feat: dynamic marker manipulation

parent 10a6ea77
No related branches found
No related tags found
1 merge request!9Feat/poi hover effects
/** @type {import("snowpack").SnowpackUserConfig } */
module.exports = {
mount: {
public: {url: '/', static: true},
src: {url: '/dist'},
public: { url: '/', static: true },
src: { url: '/dist' },
},
plugins: [
'@snowpack/plugin-react-refresh',
'@snowpack/plugin-dotenv',
'@snowpack/plugin-typescript',
'@snowpack/plugin-postcss'
'@snowpack/plugin-postcss',
],
routes: [
/* Enable an SPA Fallback in development: */
......
import React, { useState } from 'react';
import './App.css';
import SidebarListView from './Sidebar/SidebarListView';
import data from './testData.json';
import type { PointOfInterest } from './types/PointOfInterest';
......
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet';
import React from 'react';
import { MapContainer, Marker, TileLayer } from 'react-leaflet';
import React, { useMemo } from 'react';
import { divIcon, DivIconOptions } from 'leaflet';
import type { PointOfInterest } from '../types/PointOfInterest';
import type { LatLngExpression } from 'leaflet';
import MapViewController from './MapViewController';
......@@ -16,6 +17,16 @@ interface Props {
const DEFAULT_CENTER: LatLngExpression = [53.550359, 9.986701];
export const Map: React.FC<Props> = (props) => {
const iconProps: DivIconOptions = {
className: 'marker',
// Source: https://fontawesome.com/icons/map-marker-alt
html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"/></svg>`,
iconSize: [24, 32],
iconAnchor: [12, 32],
};
const icon = useMemo(() => divIcon(iconProps), [iconProps]);
const largeIcon = useMemo(() => divIcon({ ...iconProps, iconSize: [30, 40], iconAnchor: [15, 40] }), [iconProps]);
return (
<MapContainer
id={'mapid'}
......@@ -35,10 +46,13 @@ export const Map: React.FC<Props> = (props) => {
maxZoom={18}
/>
<MapViewController center={props.selectedEntry?.latlng ?? DEFAULT_CENTER} zoom={13} />
{!!props.selectedEntry && <Marker position={props.selectedEntry.latlng} />}
{/* Single marker when POI is selected */}
{!!props.selectedEntry && <Marker icon={largeIcon} position={props.selectedEntry.latlng} />}
{/* Multiple markers, when no POI is selected */}
{!props.selectedEntry &&
props.values.map((poi) => (
<Marker
icon={props.hoveredPoiId === poi.id ? largeIcon : icon}
opacity={props.hoveredPoiId === poi.id ? 1 : 0.7}
key={poi.id}
position={poi.latlng}
......
......@@ -2,16 +2,24 @@
@tailwind components;
@tailwind utilities;
:root {
--fabcity-red: #ee2f45;
--fabcity-green: #08aa64;
--fabcity-blue: #19459c;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
\ No newline at end of file
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
.marker {
color: var(--fabcity-red);
}
......@@ -28,7 +28,7 @@
},
{
"id": 4,
"latlng": [53.550359, 9.986701],
"latlng": [53.570359, 9.986701],
"name": "Fab City Haus",
"description": "Eine offene Stadtteilwerkstatt in Barmbek-Süd. Hier kann mit Holz, Metall und Elektronik gearbeitet werden.",
"address": "Jungfernstieg 1, 22083 Hamburg",
......@@ -36,7 +36,7 @@
},
{
"id": 5,
"latlng": [53.530359, 9.966701],
"latlng": [53.565359, 9.966701],
"name": "Haus Drei e. V.",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.",
"address": "Hein-Hoyer-Allee 36, 22083 Hamburg",
......
module.exports = {
purge: [],
purge: ['./src/**/*.html', './src/**/*.tsx'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
......@@ -8,4 +8,4 @@ module.exports = {
extend: {},
},
plugins: [],
}
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment