upd
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
|
||||
import ImageMarker, { MarkerComponentProps } from "react-image-marker";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import Marker from "./Marker";
|
||||
import { markers } from "../../../consts/markers";
|
||||
import useMarker from "../../../store/useMarker";
|
||||
import ZoomControlls from "./ZoomControlls";
|
||||
|
||||
const Map = () => {
|
||||
const { hoveredMarker } = useMarker();
|
||||
|
||||
const imageMarkers: MarkerComponentProps[] = markers.map((marker) => {
|
||||
return {
|
||||
top: marker.top,
|
||||
left: marker.left,
|
||||
itemNumber: marker.itemNumber,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<TransformWrapper
|
||||
initialScale={isMobile ? 2 : 1}
|
||||
minScale={isMobile ? 2 : 1}
|
||||
maxScale={2}
|
||||
alignmentAnimation={{ sizeX: 50, sizeY: 50 }}
|
||||
wheel={{ step: 10000, smoothStep: 0.0005 }}
|
||||
zoomAnimation={{
|
||||
size: 0,
|
||||
animationType: "easeOutQuart",
|
||||
animationTime: 500,
|
||||
}}
|
||||
>
|
||||
<ZoomControlls />
|
||||
<TransformComponent
|
||||
wrapperStyle={{
|
||||
width: "calc(100vw + 400px)",
|
||||
height: "calc(100vh + 150px)",
|
||||
}}
|
||||
wrapperClass={"top-[-50px] left-[-200px]"}
|
||||
>
|
||||
<ImageMarker
|
||||
src="images/Map.jpg"
|
||||
markers={imageMarkers}
|
||||
markerComponent={Marker}
|
||||
extraClass={`transition-all duration-300 ease-in-out ${
|
||||
hoveredMarker ? "brightness-[.7]" : ""
|
||||
}`}
|
||||
/>
|
||||
</TransformComponent>
|
||||
</TransformWrapper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Map;
|
||||
@@ -0,0 +1,165 @@
|
||||
import { MarkerComponentProps } from "react-image-marker";
|
||||
import { useState } from "react";
|
||||
import { useTransformEffect } from "react-zoom-pan-pinch";
|
||||
import { markers } from "../../../consts/markers";
|
||||
import useMarker from "../../../store/useMarker";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const Marker = (props: MarkerComponentProps) => {
|
||||
const { setHoveredMarker, hoveredMarker } = useMarker();
|
||||
const [markerScale, setMarkerScale] = useState(0.5);
|
||||
const navigate = useNavigate();
|
||||
const currentMarker = markers.find(
|
||||
(marker) => marker.itemNumber === props.itemNumber
|
||||
);
|
||||
|
||||
const handleOnMouseEnter = () => {
|
||||
const hoveredMarker = currentMarker ? currentMarker : null;
|
||||
setHoveredMarker(hoveredMarker);
|
||||
};
|
||||
|
||||
const handleOnMouseLeave = () => {
|
||||
setHoveredMarker(null);
|
||||
};
|
||||
|
||||
const handleOnClick = () => {
|
||||
if (!currentMarker || currentMarker?.isDisabled) return;
|
||||
navigate(`../masterplan/${currentMarker?.itemNumber}`);
|
||||
setHoveredMarker(null);
|
||||
};
|
||||
|
||||
useTransformEffect(({ state }) => {
|
||||
const scale = 1 / state.scale;
|
||||
setMarkerScale(scale);
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative transition-transform"
|
||||
style={{ transform: `scale(${markerScale})` }}
|
||||
>
|
||||
{!currentMarker?.isDisabled ? (
|
||||
<div
|
||||
className={`flex items-end absolute w-[108px] top-[30px] right-[76px] transition-all duration-300 ease-in-out ${
|
||||
hoveredMarker &&
|
||||
hoveredMarker.itemNumber !== currentMarker?.itemNumber
|
||||
? "brightness-[.7]"
|
||||
: ""
|
||||
} ${currentMarker?.isPopupLeft ? "block" : "hidden"}`}
|
||||
>
|
||||
<div className={`flex items-center py-2`}>
|
||||
<div className={`bg-white px-2 py-1 rounded-lg`}>
|
||||
{currentMarker && (
|
||||
<img
|
||||
src={currentMarker.popup}
|
||||
alt="1"
|
||||
width={108}
|
||||
height={54}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative w-[5.5px] h-[8px]">
|
||||
<div className="w-0 h-0 border-y-4 border-l-8 border-r-0 border-transparent border-l-[#fff] absolute top-0 -left-[2.5px]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={`flex items-end absolute w-[130px] top-[40px] right-[72px] transition-all duration-300 ease-in-out ${
|
||||
hoveredMarker &&
|
||||
hoveredMarker.itemNumber !== currentMarker?.itemNumber
|
||||
? "brightness-[.7]"
|
||||
: ""
|
||||
} ${currentMarker?.isPopupLeft ? "block" : "hidden"}`}
|
||||
>
|
||||
<div className={`flex items-center py-2 `}>
|
||||
<div
|
||||
className={`bg-white px-2 py-1 rounded-lg text-base font-semibold`}
|
||||
>
|
||||
Coming Soon
|
||||
</div>
|
||||
<div className="relative w-[5.5px] h-2">
|
||||
<div className="w-0 h-0 border-y-4 border-l-8 border-r-0 border-transparent border-l-[#fff] absolute top-0 -left-[2.5px]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{currentMarker?.itemNumber === 0 ? (
|
||||
<div
|
||||
className={`flex gap-[4px] transition-all duration-300 ease-in-out cursor-pointer ${
|
||||
hoveredMarker &&
|
||||
hoveredMarker.itemNumber !== currentMarker?.itemNumber
|
||||
? "brightness-[.7]"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
onMouseEnter={handleOnMouseEnter}
|
||||
onMouseLeave={handleOnMouseLeave}
|
||||
>
|
||||
<img
|
||||
id="marker"
|
||||
src={currentMarker?.imgSrc}
|
||||
alt="1"
|
||||
width={72}
|
||||
height={98}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
onClick={handleOnClick}
|
||||
className={`flex gap-[4px] transition-all duration-300 ease-in-out cursor-pointer ${
|
||||
hoveredMarker &&
|
||||
hoveredMarker.itemNumber !== currentMarker?.itemNumber
|
||||
? "brightness-[.7]"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
onMouseEnter={handleOnMouseEnter}
|
||||
onMouseLeave={handleOnMouseLeave}
|
||||
>
|
||||
<img
|
||||
id="marker"
|
||||
src={currentMarker?.imgSrc}
|
||||
alt="1"
|
||||
width={72}
|
||||
height={98}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!currentMarker?.isDisabled && (
|
||||
<div
|
||||
className={`flex items-end absolute w-[108px] top-[30px] left-[76px] transition-all duration-300 ease-in-out ${
|
||||
currentMarker?.isPopupLeft ? "hidden" : "block"
|
||||
} ${
|
||||
hoveredMarker &&
|
||||
hoveredMarker.itemNumber !== currentMarker?.itemNumber
|
||||
? "brightness-[.7]"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className={`flex items-center py-[8px]`}>
|
||||
<div className="relative w-[5.5px] h-[8px]">
|
||||
<div className="w-0 h-0 border-y-[4px] border-r-[8px] border-l-0 border-transparent border-r-[#fff] absolute top-0 -right-[2.5px]" />
|
||||
</div>
|
||||
<div className={`bg-white px-[8px] py-[4px] rounded-[8px]`}>
|
||||
{currentMarker && (
|
||||
<img
|
||||
src={currentMarker.popup}
|
||||
alt="1"
|
||||
width={108}
|
||||
height={54}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Marker;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useControls } from "react-zoom-pan-pinch";
|
||||
import Button from "../../Button";
|
||||
import UnzoomIcon from "../../icons/UnzoomIcon";
|
||||
import ZoomIcon from "../../icons/ZoomIcon";
|
||||
|
||||
const ZoomControlls = () => {
|
||||
const { zoomIn, zoomOut } = useControls();
|
||||
const handleOnZoomClick = () => {
|
||||
zoomIn();
|
||||
};
|
||||
|
||||
const handleOnUnzoomClick = () => {
|
||||
zoomOut();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="absolute top-1/2 right-4 z-50 flex flex-col gap-2">
|
||||
<Button
|
||||
buttonType="primary"
|
||||
icon={<ZoomIcon />}
|
||||
isCircleRounded
|
||||
onClick={handleOnZoomClick}
|
||||
/>
|
||||
<Button
|
||||
buttonType="primary"
|
||||
icon={<UnzoomIcon />}
|
||||
isCircleRounded
|
||||
onClick={handleOnUnzoomClick}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ZoomControlls;
|
||||
Reference in New Issue
Block a user