From 4fe131889319a898518c457d896f2784c5e9bc15 Mon Sep 17 00:00:00 2001 From: Timothy Armes Date: Wed, 19 Jul 2023 15:58:56 +0200 Subject: [PATCH] Remove shadow and bounce contraction for cleaner look --- app/[lang]/tournois/TournamentMap.tsx | 20 ++++++++------- app/[lang]/tournois/TournamentMarker.tsx | 31 +++++++++++++++++++----- leafletTypes.ts | 29 ++++++++++++++++++++++ 3 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 leafletTypes.ts diff --git a/app/[lang]/tournois/TournamentMap.tsx b/app/[lang]/tournois/TournamentMap.tsx index 4f78d5e..f4a875a 100644 --- a/app/[lang]/tournois/TournamentMap.tsx +++ b/app/[lang]/tournois/TournamentMap.tsx @@ -30,7 +30,7 @@ import { generatePieSVG } from "@/lib/pie"; import { TimeControlColours } from "@/app/constants"; import Legend from "./Legend"; -import { TournamentMarker } from "./TournamentMarker"; +import { TournamentMarker, TournamentMarkerRef } from "./TournamentMarker"; import TimeControlFilters from "./TimeControlFilters"; // Declare a class type that adds in methods etc. defined by leaflet.smooth_marker_bouncing @@ -100,7 +100,7 @@ export default function TournamentMap() { debouncedHoveredListTournamentIdAtom, ); - const markerRefs = useRef | null>>({}); + const markerRefs = useRef>({}); const clusterRef = useRef(null); const expandedClusterMarkerRef = useRef(null); @@ -134,7 +134,9 @@ export default function TournamentMap() { const markerRef = markerRefs.current[tournament.groupId]; if (markerRef) { if (clusterRef.current) { - const visibleMarker = clusterRef.current.getVisibleParent(markerRef); + const visibleMarker = clusterRef.current.getVisibleParent( + markerRef.getMarker(), + ); if (!visibleMarker) return; // @ts-ignore @@ -163,7 +165,7 @@ export default function TournamentMap() { if (!marker.isBouncing()) { stopBouncingMarkers(); - marker.bounce(); + markerRef.bounce(); } } @@ -186,11 +188,9 @@ export default function TournamentMap() { if (!tournament) return; expandedClusterMarkerRef.current = e.cluster; - const markerRef = markerRefs.current[ - tournament.groupId - ] as BouncingMarker; + const markerRef = markerRefs.current[tournament.groupId]; - if (markerRef && e.markers.includes(markerRef)) { + if (markerRef && e.markers.includes(markerRef.getMarker())) { stopBouncingMarkers(); markerRef.bounce(); } @@ -284,7 +284,9 @@ export default function TournamentMap() { return ( (markerRefs.current[groupId] = ref)} + ref={(ref) => { + markerRefs.current[groupId] = ref!; + }} key={groupId} tournamentGroup={tournamentGroup} colour={colours[timeControl]} diff --git a/app/[lang]/tournois/TournamentMarker.tsx b/app/[lang]/tournois/TournamentMarker.tsx index a701c7c..471d5f2 100644 --- a/app/[lang]/tournois/TournamentMarker.tsx +++ b/app/[lang]/tournois/TournamentMarker.tsx @@ -1,7 +1,7 @@ "use client"; -import { forwardRef, useMemo, useRef } from "react"; -import { TimeControl, Tournament } from "@/types"; +import { forwardRef, useMemo, useImperativeHandle, useRef } from "react"; +import { Tournament } from "@/types"; import L from "leaflet"; import { Marker, Popup, MarkerProps } from "react-leaflet"; import { useTranslations } from "next-intl"; @@ -9,18 +9,38 @@ import { useSetAtom } from "jotai"; import { FaTrophy } from "react-icons/fa"; import { last } from "lodash"; +import type { BouncingMarker } from "@/leafletTypes"; import { debouncedHoveredMapTournamentGroupIdAtom } from "@/app/atoms"; +export type TournamentMarkerRef = { + getMarker: () => L.Marker; + bounce: () => void; +}; + type TournamentMarkerProps = { tournamentGroup: Tournament[]; colour: string; } & Omit; export const TournamentMarker = forwardRef< - L.Marker | null, + TournamentMarkerRef, TournamentMarkerProps >(({ tournamentGroup, colour, ...markerProps }, ref) => { const t = useTranslations("Tournaments"); + const markerRef = useRef | null>(null); + + useImperativeHandle( + ref, + () => ({ + getMarker: () => markerRef.current!, + bounce: () => { + const bouncingMarker = markerRef.current as BouncingMarker; + bouncingMarker.setBouncingOptions({ contractHeight: 0 }); + bouncingMarker.bounce(); + }, + }), + [], + ); const { date, latLng, groupId, timeControl } = tournamentGroup[0]; @@ -32,11 +52,10 @@ export const TournamentMarker = forwardRef< () => new L.Icon({ iconUrl: `/images/leaflet/marker-icon-2x-${colour}.png`, - shadowUrl: "/images/leaflet/marker-shadow.png", iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], - shadowSize: [41, 41], + timeControl, }), [colour, timeControl], @@ -47,7 +66,7 @@ export const TournamentMarker = forwardRef< return ( ); +} + +// Declare a class type that adds in methods etc. defined by leaflet.smooth_marker_bouncing +// to keep Typescript happy +export declare class BouncingMarker extends Marker { + isBouncing(): boolean; + bounce(): void; + stopBouncing(): void; + getBouncingMarkers(): Marker[]; + setBouncingOptions(options: BouncingOptions | Partial): void; + stopAllBouncingMarkers(): void; + + _icon: HTMLElement; + _bouncingMotion?: { + bouncingAnimationPlaying: boolean; + }; +}