From 28928a40cabb46e22b5ce71c3aa83ebb122960c5 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello <fabio@manganiello.tech> Date: Sat, 22 Feb 2025 17:23:38 +0100 Subject: [PATCH] Style improvements. - Improved POI style (a bit bigger and with border) - Improved styling of the close buttons. - Added palette with accent/background colors. --- frontend/src/assets/base.css | 43 ++++++++++++++++++++++ frontend/src/components/Map.vue | 51 +++++++++++++++++---------- frontend/src/components/PointInfo.vue | 28 ++++++++++++++- 3 files changed, 102 insertions(+), 20 deletions(-) diff --git a/frontend/src/assets/base.css b/frontend/src/assets/base.css index 8816868..86ae22f 100644 --- a/frontend/src/assets/base.css +++ b/frontend/src/assets/base.css @@ -19,6 +19,47 @@ --vt-c-text-light-2: rgba(60, 60, 60, 0.66); --vt-c-text-dark-1: var(--vt-c-white); --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); + + --vt-c-blue-fg-light: #3498db; + --vt-c-blue-fg-dark: #2980b9; + --vt-c-blue-bg-light: #5bc0de; + --vt-c-blue-bg-dark: #31b0d5; + --vt-c-green-fg-light: #2ecc71; + --vt-c-green-fg-dark: #27ae60; + --vt-c-green-bg-light: #5cb85c; + --vt-c-green-bg-dark: #449d44; + --vt-c-red-fg-light: #e74c3c; + --vt-c-red-fg-dark: #c0392b; + --vt-c-red-bg-light: #d9534f; + --vt-c-red-bg-dark: #c9302c; + --vt-c-yellow-fg-light: #f1c40f; + --vt-c-yellow-fg-dark: #f39c12; + --vt-c-yellow-bg-light: #f0ad4e; + --vt-c-yellow-bg-dark: #ec971f; + --vt-c-purple-fg-light: #9b59b6; + --vt-c-purple-fg-dark: #8e44ad; + --vt-c-purple-bg-light: #9d71d9; + --vt-c-purple-bg-dark: #8e44ad; + --vt-c-cyan-fg-light: #1abc9c; + --vt-c-cyan-fg-dark: #16a085; + --vt-c-cyan-bg-light: #5bc0de; + --vt-c-cyan-bg-dark: #31b0d5; + --vt-c-orange-fg-light: #e67e22; + --vt-c-orange-fg-dark: #d35400; + --vt-c-orange-bg-light: #f0ad4e; + --vt-c-orange-bg-dark: #ec971f; + --vt-c-pink-fg-light: #e91e63; + --vt-c-pink-fg-dark: #d81b60; + --vt-c-pink-bg-light: #d9534f; + --vt-c-pink-bg-dark: #c9302c; + --vt-c-teal-fg-light: #1abc9c; + --vt-c-teal-fg-dark: #16a085; + --vt-c-teal-bg-light: #5bc0de; + --vt-c-teal-bg-dark: #31b0d5; + --vt-c-lime-fg-light: #2ecc71; + --vt-c-lime-fg-dark: #27ae60; + --vt-c-lime-bg-light: #5cb85c; + --vt-c-lime-bg-dark: #449d44; } /* semantic color variables for this project */ @@ -32,6 +73,7 @@ --color-heading: var(--vt-c-text-light-1); --color-text: var(--vt-c-text-light-1); + --color-accent: var(--vt-c-blue-fg-light); --section-gap: 160px; } @@ -47,6 +89,7 @@ --color-heading: var(--vt-c-text-dark-1); --color-text: var(--vt-c-text-dark-2); + --color-accent: var(--vt-c-blue-fg-dark); } } diff --git a/frontend/src/components/Map.vue b/frontend/src/components/Map.vue index 2370f6f..0e206ee 100644 --- a/frontend/src/components/Map.vue +++ b/frontend/src/components/Map.vue @@ -13,6 +13,7 @@ import Feature from 'ol/Feature'; import GPSPoint from '../models/GPSPoint'; import Map from 'ol/Map'; +import LineString from 'ol/geom/LineString'; import OSM from 'ol/source/OSM'; import Overlay from 'ol/Overlay'; import Point from 'ol/geom/Point'; @@ -21,9 +22,9 @@ import VectorLayer from 'ol/layer/Vector'; import VectorSource from 'ol/source/Vector'; import View from 'ol/View'; import TileLayer from 'ol/layer/Tile'; -import { Circle, Fill, Style } from 'ol/style'; +import { Circle, Fill, Style, Stroke } from 'ol/style'; import { useGeographic } from 'ol/proj'; -import { type Nullable } from '../models/Types'; +import type { Nullable } from '../models/Types'; // @ts-ignore const baseURL = __API_PATH__ @@ -40,6 +41,7 @@ export default { loading: false, map: null as Nullable<Map>, popup: null as Nullable<Overlay>, + routeFeatures: [] as Feature[], selectedPoint: null as Nullable<GPSPoint>, } }, @@ -60,32 +62,41 @@ export default { } }, + osmLayer() { + return new TileLayer({ + source: new OSM(), + }) + }, + + pointsLayer(points: Point[]) { + const pointFeatures = points.map((point: Point) => new Feature(point)) + return new VectorLayer({ + source: new VectorSource({ + features: pointFeatures, + }), + style: new Style({ + image: new Circle({ + radius: 6, + fill: new Fill({ color: 'red' }), + stroke: new Stroke({ color: 'black', width: 1 }), + }), + zIndex: Infinity, // Ensure that points are always displayed above other layers + }), + }) + }, + createMap(gpsPoints: GPSPoint[]) { const points = gpsPoints.map((gps: GPSPoint) => { const point = new Point([gps.longitude, gps.latitude]) return point - }) + }); - const pointFeatures = points.map((point: Point) => new Feature(point)) const view = new View(this.getCenterAndZoom()) const map = new Map({ target: 'map', layers: [ - new TileLayer({ - source: new OSM(), - }), - - new VectorLayer({ - source: new VectorSource({ - features: pointFeatures, - }), - style: new Style({ - image: new Circle({ - radius: 5, - fill: new Fill({ color: 'red' }), - }), - }), - }), + this.osmLayer(), + this.pointsLayer(points), ], view: view }) @@ -130,6 +141,8 @@ export default { this.selectedPoint = point // @ts-expect-error this.$refs.popup.setPosition(event.coordinate) + // Center the map on the selected point + map.getView().setCenter(event.coordinate) } } else { this.selectedPoint = null diff --git a/frontend/src/components/PointInfo.vue b/frontend/src/components/PointInfo.vue index bc30196..1c4e604 100644 --- a/frontend/src/components/PointInfo.vue +++ b/frontend/src/components/PointInfo.vue @@ -1,7 +1,9 @@ <template> <div class="popup" :class="{ hidden: !point }" ref="popup"> <div class="popup-content" v-if="point"> - <button @click="$emit('close')">Close</button> + <div class="header"> + <button @click="$emit('close')" title="Close">✕</button> + </div> <div class="point-info"> <h2 class="address" v-if="point.address">{{ point.address }}</h2> <h2 class="latlng" v-else>{{ point.latitude }}, {{ point.longitude }}</h2> @@ -90,6 +92,30 @@ export default { border-radius: 1em; box-shadow: 2px 2px 2px 2px var(--color-border); + .popup-content { + display: flex; + flex-direction: column; + gap: 1.5em; + } + + .header { + position: absolute; + top: 0.5em; + right: 0.5em; + + button { + background: none; + border: none; + color: var(--color-heading); + font-size: 1.2em; + cursor: pointer; + + &:hover { + color: var(--color-accent); + } + } + } + &.hidden { padding: 0; border-radius: 0;