Skip to content

Commit

Permalink
feat(ts/components/vehicleMarker): move Vehicle Icon and Vehicle Labe…
Browse files Browse the repository at this point in the history
…l into ReactMarker
  • Loading branch information
firestack committed Oct 10, 2024
1 parent 5e90bac commit 1a93e56
Show file tree
Hide file tree
Showing 3 changed files with 306 additions and 341 deletions.
155 changes: 72 additions & 83 deletions assets/src/components/mapMarkers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import vehicleLabelString from "../helpers/vehicleLabel"
import { drawnStatus, statusClasses } from "../models/vehicleStatus"
import { TrainVehicle, Vehicle } from "../realtime"
import { Shape, Stop } from "../schedule"
import { UserSettings } from "../userSettings"

import garages, { Garage as GarageData } from "../data/garages"
import useDeviceSupportsHover from "../hooks/useDeviceSupportsHover"
Expand All @@ -37,71 +36,6 @@ import { fullStoryEvent } from "../helpers/fullStory"

/* eslint-enable @typescript-eslint/ban-ts-comment */

const makeVehicleIcon = (
vehicle: Vehicle,
isPrimary: boolean,
userSettings: UserSettings,
isSelected: boolean
): Leaflet.DivIcon => {
const centerX = 12
const centerY = 12
return Leaflet.divIcon({
html: `<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
class="${joinClasses([
...statusClasses(
drawnStatus(vehicle),
userSettings.vehicleAdherenceColors
),
isSelected ? "selected" : null,
])}"
d="m10 2.7-6.21 16.94a2.33 2.33 0 0 0 1.38 3 2.36 2.36 0 0 0 1.93-.14l4.9-2.67 4.89 2.71a2.34 2.34 0 0 0 3.34-2.8l-5.81-17a2.34 2.34 0 0 0 -4.4 0z"
transform="scale(${isPrimary ? 1.0 : 0.8}) rotate(${
vehicle.bearing || 0
}) translate(${-centerX}, ${-centerY})"
/>
</svg>`,
iconAnchor: [0, 0],
className: "c-vehicle-map__icon",
})
}

const makeLabelIcon = (
vehicle: Vehicle,
isPrimary: boolean,
settings: UserSettings,
isSelected: boolean
): Leaflet.DivIcon => {
const labelString = vehicleLabelString(vehicle, settings)
const labelBackgroundHeight = isPrimary ? 16 : 12
const labelBackgroundWidth =
labelString.length <= 4 ? (isPrimary ? 40 : 30) : isPrimary ? 62 : 40
const selectedClass = isSelected ? "selected" : null
return Leaflet.divIcon({
className: joinClasses([
"c-vehicle-map__label",
isPrimary ? "primary" : "secondary",
selectedClass,
]),
html: `<svg viewBox="0 0 ${labelBackgroundWidth} ${labelBackgroundHeight}" width="${labelBackgroundWidth}" height="${labelBackgroundHeight}">
<rect
class="c-vehicle-icon__label-background"
width="100%" height="100%"
rx="5.5px" ry="5.5px"
/>
<text class="c-vehicle-icon__label" x="50%" y="50%" text-anchor="middle" dominant-baseline="central">
${labelString}
</text>
</svg>`,
iconAnchor: [labelBackgroundWidth / 2, isPrimary ? -16 : -10],
})
}

interface VehicleMarkerProps extends PropsWithChildren {
vehicle: Vehicle
isPrimary: boolean
Expand Down Expand Up @@ -152,18 +86,15 @@ export const VehicleMarker = ({
},
}
const position: LatLngExpression = [vehicle.latitude, vehicle.longitude]
const vehicleIcon: Leaflet.DivIcon = makeVehicleIcon(
vehicle,
isPrimary,
userSettings,
isSelected
)
const labelIcon: Leaflet.DivIcon = makeLabelIcon(
vehicle,
isPrimary,
userSettings,
isSelected
)
const labelBackgroundHeight = isPrimary ? 16 : 12
const labelBackgroundWidth =
vehicleLabelString(vehicle, userSettings).length <= 4
? isPrimary
? 40
: 30
: isPrimary
? 62
: 40

// https://leafletjs.com/reference.html#marker-zindexoffset
// > By default, marker images zIndex is set automatically based on its latitude
Expand All @@ -173,19 +104,77 @@ export const VehicleMarker = ({

return (
<>
<Marker
<ReactMarker
position={position}
icon={vehicleIcon}
eventHandlers={eventHandlers}
zIndexOffset={zIndexOffset}
ref={markerRef}
divIconSettings={{
iconAnchor: [0, 0],
className: "c-vehicle-map__icon",
}}
icon={
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
className={joinClasses([
...statusClasses(
drawnStatus(vehicle),
userSettings.vehicleAdherenceColors
),
isSelected ? "selected" : null,
])}
d="m10 2.7-6.21 16.94a2.33 2.33 0 0 0 1.38 3 2.36 2.36 0 0 0 1.93-.14l4.9-2.67 4.89 2.71a2.34 2.34 0 0 0 3.34-2.8l-5.81-17a2.34 2.34 0 0 0 -4.4 0z"
transform={
`scale(${isPrimary ? 1.0 : 0.8}) ` +
`rotate(${vehicle.bearing || 0}) ` +
`translate(-12, -12)`
}
/>
</svg>
}
>
{children}
</Marker>
</ReactMarker>

<Marker
<ReactMarker
position={position}
icon={labelIcon}
divIconSettings={{
iconAnchor: [labelBackgroundWidth / 2, isPrimary ? -16 : -10],
className: joinClasses([
"c-vehicle-map__label",
isPrimary ? "primary" : "secondary",
isSelected && "selected",
]),
}}
icon={
<svg
viewBox={`0 0 ${labelBackgroundWidth} ${labelBackgroundHeight}`}
width={labelBackgroundWidth}
height={labelBackgroundHeight}
>
<rect
className="c-vehicle-icon__label-background"
width="100%"
height="100%"
rx="5.5px"
ry="5.5px"
/>
<text
className="c-vehicle-icon__label"
x="50%"
y="50%"
textAnchor="middle"
dominantBaseline="central"
>
{vehicleLabelString(vehicle, userSettings)}
</text>
</svg>
}
eventHandlers={eventHandlers}
zIndexOffset={zIndexOffset}
/>
Expand Down
164 changes: 78 additions & 86 deletions assets/tests/components/__snapshots__/mapPage.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1780,119 +1780,111 @@ exports[`<MapPage /> Snapshot renders vehicle data 1`] = `
style="margin-left: 0px; margin-top: 0px; width: 12px; height: 12px; left: 223px; top: 27px; z-index: 1027;"
tabindex="0"
>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
<div
class="w-100 h-100"
>
<path
class="on-time early-red selected"
d="m10 2.7-6.21 16.94a2.33 2.33 0 0 0 1.38 3 2.36 2.36 0 0 0 1.93-.14l4.9-2.67 4.89 2.71a2.34 2.34 0 0 0 3.34-2.8l-5.81-17a2.34 2.34 0 0 0 -4.4 0z"
transform="scale(1) rotate(33) translate(-12, -12)"
/>
</svg>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
class="on-time early-red selected"
d="m10 2.7-6.21 16.94a2.33 2.33 0 0 0 1.38 3 2.36 2.36 0 0 0 1.93-.14l4.9-2.67 4.89 2.71a2.34 2.34 0 0 0 3.34-2.8l-5.81-17a2.34 2.34 0 0 0 -4.4 0z"
transform="scale(1) rotate(33) translate(-12, -12)"
/>
</svg>
</div>
</div>
<div
class="leaflet-marker-icon c-vehicle-map__label primary selected leaflet-zoom-hide leaflet-interactive"
role="button"
style="margin-left: -20px; margin-top: 16px; width: 12px; height: 12px; left: 223px; top: 27px; z-index: 1027;"
tabindex="0"
>
<svg
height="16"
viewBox="0 0 40 16"
width="40"
<div
class="w-100 h-100"
>
<rect
class="c-vehicle-icon__label-background"
height="100%"
rx="5.5px"
ry="5.5px"
width="100%"
/>
<text
class="c-vehicle-icon__label"
dominant-baseline="central"
text-anchor="middle"
x="50%"
y="50%"
<svg
height="16"
viewBox="0 0 40 16"
width="40"
>
1
</text>
</svg>
<rect
class="c-vehicle-icon__label-background"
height="100%"
rx="5.5px"
ry="5.5px"
width="100%"
/>
<text
class="c-vehicle-icon__label"
dominant-baseline="central"
text-anchor="middle"
x="50%"
y="50%"
>
1
</text>
</svg>
</div>
</div>
<div
class="leaflet-marker-icon c-vehicle-map__icon leaflet-zoom-hide leaflet-interactive"
role="button"
style="margin-left: 0px; margin-top: 0px; width: 12px; height: 12px; left: 223px; top: 27px; z-index: 27; z-index: 27;"
tabindex="0"
>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
<div
class="w-100 h-100"
>
<path
class="on-time early-red"
d="m10 2.7-6.21 16.94a2.33 2.33 0 0 0 1.38 3 2.36 2.36 0 0 0 1.93-.14l4.9-2.67 4.89 2.71a2.34 2.34 0 0 0 3.34-2.8l-5.81-17a2.34 2.34 0 0 0 -4.4 0z"
transform="scale(0.8) rotate(33) translate(-12, -12)"
/>
</svg>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
class="on-time early-red"
d="m10 2.7-6.21 16.94a2.33 2.33 0 0 0 1.38 3 2.36 2.36 0 0 0 1.93-.14l4.9-2.67 4.89 2.71a2.34 2.34 0 0 0 3.34-2.8l-5.81-17a2.34 2.34 0 0 0 -4.4 0z"
transform="scale(0.8) rotate(33) translate(-12, -12)"
/>
</svg>
</div>
</div>
<div
class="leaflet-marker-icon c-vehicle-map__label secondary leaflet-zoom-hide leaflet-interactive"
role="button"
style="margin-left: -15px; margin-top: 10px; width: 12px; height: 12px; left: 223px; top: 27px; z-index: 27; z-index: 27;"
tabindex="0"
>
<svg
height="12"
viewBox="0 0 30 12"
width="30"
<div
class="w-100 h-100"
>
<rect
class="c-vehicle-icon__label-background"
height="100%"
rx="5.5px"
ry="5.5px"
width="100%"
/>
<text
class="c-vehicle-icon__label"
dominant-baseline="central"
text-anchor="middle"
x="50%"
y="50%"
<svg
height="12"
viewBox="0 0 30 12"
width="30"
>
2
</text>
</svg>
<rect
class="c-vehicle-icon__label-background"
height="100%"
rx="5.5px"
ry="5.5px"
width="100%"
/>
<text
class="c-vehicle-icon__label"
dominant-baseline="central"
text-anchor="middle"
x="50%"
y="50%"
>
2
</text>
</svg>
</div>
</div>
</div>
<div
Expand Down
Loading

0 comments on commit 1a93e56

Please sign in to comment.