Added marker clustering when zoomed out
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import { cn } from "helpers/cn";
|
||||
import { RefAttributes, useEffect, useImperativeHandle } from "react";
|
||||
import {
|
||||
RefAttributes,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
} from "react";
|
||||
import { createContext, Ref, useContext, useState } from "react";
|
||||
import { Popup, PopupProps, useMap } from "react-leaflet";
|
||||
import { Popup as LPopup, popup } from "leaflet";
|
||||
import { Popup as LPopup } from "leaflet";
|
||||
|
||||
const PopupContext = createContext({
|
||||
anchor: "topleft",
|
||||
@@ -16,7 +21,11 @@ export const useSmartPopup = () => {
|
||||
return context;
|
||||
};
|
||||
|
||||
export const calculateAnchor = (id: string, mode: "popup" | "marker") => {
|
||||
export const calculateAnchor = (
|
||||
id: string,
|
||||
mode: "popup" | "marker",
|
||||
ignoreMarker?: boolean,
|
||||
) => {
|
||||
const otherMarkers = document.querySelectorAll(".map-collision");
|
||||
// get markers and check if they are overlapping
|
||||
const ownMarker =
|
||||
@@ -28,6 +37,7 @@ export const calculateAnchor = (id: string, mode: "popup" | "marker") => {
|
||||
|
||||
const marksersInCluster = Array.from(otherMarkers).filter((marker) => {
|
||||
if (mode === "popup" && marker.id === `marker-${id}`) return false;
|
||||
if (ignoreMarker && marker.id.startsWith("marker")) return false;
|
||||
|
||||
const rect1 = (marker as HTMLElement).getBoundingClientRect();
|
||||
const rect2 = (ownMarker as HTMLElement).getBoundingClientRect();
|
||||
@@ -90,24 +100,24 @@ export interface SmartPopupRef {
|
||||
}
|
||||
|
||||
export const SmartPopup = (
|
||||
props: PopupProps &
|
||||
RefAttributes<LPopup> & {
|
||||
props: PopupProps & { ignoreMarker?: boolean } & RefAttributes<LPopup> & {
|
||||
smartPopupRef?: Ref<SmartPopupRef>;
|
||||
id: string;
|
||||
wrapperClassName?: string;
|
||||
},
|
||||
) => {
|
||||
const [showContent, setShowContent] = useState(false);
|
||||
const { smartPopupRef, id, className, wrapperClassName } = props;
|
||||
const { smartPopupRef, id, className, wrapperClassName, ignoreMarker } =
|
||||
props;
|
||||
|
||||
const [anchor, setAnchor] = useState<
|
||||
"topleft" | "topright" | "bottomleft" | "bottomright"
|
||||
>("topleft");
|
||||
|
||||
const handleConflict = () => {
|
||||
const newAnchor = calculateAnchor(id, "popup");
|
||||
const handleConflict = useCallback(() => {
|
||||
const newAnchor = calculateAnchor(id, "popup", ignoreMarker);
|
||||
setAnchor(newAnchor);
|
||||
};
|
||||
}, [id, ignoreMarker]);
|
||||
|
||||
useImperativeHandle(smartPopupRef, () => ({
|
||||
handleConflict,
|
||||
@@ -125,7 +135,7 @@ export const SmartPopup = (
|
||||
return () => {
|
||||
map.off("zoom", handleConflict);
|
||||
};
|
||||
}, [map, anchor]);
|
||||
}, [map, handleConflict]);
|
||||
|
||||
return (
|
||||
<Popup {...props} className={cn("relative", wrapperClassName)}>
|
||||
|
||||
Reference in New Issue
Block a user