86 lines
2.2 KiB
TypeScript
86 lines
2.2 KiB
TypeScript
import { useRef } from "react";
|
|
import IMarker from "../types/IMarker";
|
|
import clsx from "clsx";
|
|
import { isMobile } from "react-device-detect";
|
|
import { useNavigate } from "react-router";
|
|
|
|
interface MarkerProps {
|
|
marker: IMarker;
|
|
zoom: number;
|
|
hoveredMarker: IMarker | null;
|
|
lastHoveredMarker: IMarker | null;
|
|
onHover: (marker: IMarker | null) => void;
|
|
maxZoom: number;
|
|
}
|
|
|
|
function Marker({
|
|
marker,
|
|
zoom,
|
|
hoveredMarker,
|
|
lastHoveredMarker,
|
|
onHover,
|
|
maxZoom,
|
|
}: MarkerProps) {
|
|
const popupRef = useRef<HTMLImageElement>(null);
|
|
|
|
const navigate = useNavigate();
|
|
|
|
return (
|
|
<div
|
|
id="marker"
|
|
key={marker.id}
|
|
className={clsx(
|
|
"absolute -translate-x-1/2 -translate-y-1/2 cursor-pointer will-change-[transform,filter,scale,translate] transition-[transform,filter,scale,translate] select-none duration-300 max-sm:[scale:70%] [scale:80%]",
|
|
hoveredMarker
|
|
? hoveredMarker.id === marker.id
|
|
? "max-sm:[scale:80%] [scale:90%]"
|
|
: "brightness-[80%]"
|
|
: "",
|
|
lastHoveredMarker?.id === marker.id ? "z-10" : ""
|
|
)}
|
|
style={{
|
|
top: marker.y,
|
|
left: marker.x,
|
|
transform: `scale(${maxZoom / zoom})`,
|
|
}}
|
|
onMouseEnter={() => {
|
|
if (marker.disabled) return;
|
|
onHover(marker);
|
|
}}
|
|
onMouseLeave={() => {
|
|
if (isMobile) return;
|
|
onHover(null);
|
|
}}
|
|
onClick={() => {
|
|
if (!isMobile && !marker.disabled) {
|
|
navigate(`/complex/${marker.name}`);
|
|
}
|
|
}}
|
|
>
|
|
<img
|
|
src={`/images/map/markers/${marker.name}.png`}
|
|
alt={marker.title}
|
|
className="pointer-events-none"
|
|
/>
|
|
<div
|
|
className={clsx(
|
|
"absolute bottom-[10%]ф top-1/2 -translate-y-1/2",
|
|
marker.popupPosition === "left" ? "right-full" : "left-full"
|
|
)}
|
|
>
|
|
<img
|
|
ref={popupRef}
|
|
src={`/images/map/markers/popups/${marker.name}.png`}
|
|
alt={marker.title}
|
|
className="pointer-events-none"
|
|
style={{
|
|
minWidth: `${popupRef.current?.naturalWidth}px`,
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default Marker;
|