start and finish markers, stronger segment glow, edit form spacing
This commit is contained in:
@@ -217,6 +217,35 @@
|
||||
);
|
||||
});
|
||||
|
||||
// start/finish markers for the highlighted route or the live selection
|
||||
function endpointsGeojson(): FeatureCollection {
|
||||
const line =
|
||||
selection && selection.length > 1
|
||||
? selection
|
||||
: highlightId !== null
|
||||
? tracks.find((t) => t.id === highlightId)?.latlngs
|
||||
: undefined;
|
||||
if (!line || line.length < 2) return { type: 'FeatureCollection', features: [] };
|
||||
const make = (kind: string, [lat, lon]: [number, number]) => ({
|
||||
type: 'Feature' as const,
|
||||
properties: { kind },
|
||||
geometry: { type: 'Point' as const, coordinates: [lon, lat] }
|
||||
});
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: [make('start', line[0]), make('end', line[line.length - 1])]
|
||||
};
|
||||
}
|
||||
$effect(() => {
|
||||
void selection;
|
||||
void tracks;
|
||||
void highlightId;
|
||||
if (!loaded) return;
|
||||
(map?.getSource('endpoints') as import('maplibre-gl').GeoJSONSource | undefined)?.setData(
|
||||
endpointsGeojson()
|
||||
);
|
||||
});
|
||||
|
||||
// animate the camera when a page requests a new focus; remember the
|
||||
// unfocused camera so returning to the overview restores it instead of
|
||||
// zooming all the way back out
|
||||
@@ -279,6 +308,15 @@
|
||||
);
|
||||
|
||||
map.addSource('tracks', { type: 'geojson', data: tracksGeojson(dark) });
|
||||
// soft glow behind the highlighted route so it pops off the basemap
|
||||
map.addLayer({
|
||||
id: 'tracks-halo',
|
||||
type: 'line',
|
||||
source: 'tracks',
|
||||
filter: ['==', ['get', 'highlight'], true],
|
||||
layout: { 'line-join': 'round', 'line-cap': 'round' },
|
||||
paint: { 'line-color': ['get', 'color'], 'line-width': 14, 'line-opacity': 0.22 }
|
||||
});
|
||||
map.addLayer({
|
||||
id: 'tracks-casing',
|
||||
type: 'line',
|
||||
@@ -287,7 +325,7 @@
|
||||
paint: {
|
||||
'line-color': dark ? '#1a1a19' : '#ffffff',
|
||||
'line-width': ['case', ['get', 'highlight'], 8, 5],
|
||||
'line-opacity': ['case', ['get', 'dim'], 0.08, ['get', 'highlight'], 0.9, 0.6]
|
||||
'line-opacity': ['case', ['get', 'dim'], 0.08, ['get', 'highlight'], 0.95, 0.6]
|
||||
}
|
||||
});
|
||||
map.addLayer({
|
||||
@@ -352,6 +390,44 @@
|
||||
}
|
||||
});
|
||||
|
||||
// start / finish markers
|
||||
map.addSource('endpoints', { type: 'geojson', data: endpointsGeojson() });
|
||||
map.addLayer({
|
||||
id: 'endpoints-circles',
|
||||
type: 'circle',
|
||||
source: 'endpoints',
|
||||
paint: {
|
||||
'circle-radius': 9,
|
||||
'circle-color': [
|
||||
'case',
|
||||
['==', ['get', 'kind'], 'start'],
|
||||
'#0ca30c',
|
||||
dark ? '#eef2f0' : '#0b0b0b'
|
||||
],
|
||||
'circle-stroke-width': 2,
|
||||
'circle-stroke-color': dark ? '#1a1a19' : '#ffffff'
|
||||
}
|
||||
});
|
||||
map.addLayer({
|
||||
id: 'endpoints-glyphs',
|
||||
type: 'symbol',
|
||||
source: 'endpoints',
|
||||
layout: {
|
||||
'text-field': ['case', ['==', ['get', 'kind'], 'start'], 'S', 'F'],
|
||||
'text-size': 10,
|
||||
'text-allow-overlap': true,
|
||||
'text-ignore-placement': true
|
||||
},
|
||||
paint: {
|
||||
'text-color': [
|
||||
'case',
|
||||
['==', ['get', 'kind'], 'start'],
|
||||
'#ffffff',
|
||||
dark ? '#0b0b0b' : '#ffffff'
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// chart-hover position marker, matching the chart's crosshair dot
|
||||
map.addSource('hover-point', { type: 'geojson', data: hoverGeojson() });
|
||||
map.addLayer({
|
||||
|
||||
@@ -349,6 +349,7 @@
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.edit-form input {
|
||||
padding: 0.5rem 0.7rem;
|
||||
|
||||
Reference in New Issue
Block a user