zoom buttons

This commit is contained in:
2024-05-30 13:39:49 +05:00
parent 44413af8a2
commit 3586728262
39 changed files with 380 additions and 223 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

+2 -1
View File
@@ -18,8 +18,9 @@ const ButtomPanel = () => {
className="pl-2"
icon={<DisclaimerIcon />}
onClick={handleOnDisclaimerClick}
isCircleRounded
/>
<Button text="Privacy Policy" buttonType="special" />
<Button text="Privacy Policy" buttonType="special" isCircleRounded />
</div>
</div>
<div className="p-6">
+4 -1
View File
@@ -13,6 +13,7 @@ interface ButtonProps {
className?: string;
onClick?: () => void;
disabled?: boolean;
isCircleRounded?: boolean;
}
const Button = ({
@@ -22,17 +23,19 @@ const Button = ({
buttonType = "primary",
disabled = false,
onClick,
isCircleRounded = false,
}: ButtonProps) => {
const backgroundColor = backgroundColors[buttonType];
const textColor = textColors[buttonType];
const border = borders[buttonType];
const padding = paddings[buttonType];
const rounded = isCircleRounded ? "rounded-full" : "rounded-lg";
return (
<button
disabled={disabled}
onClick={onClick}
className={`min-w-10 max-h-10 ${
className={`min-w-10 max-h-10 ${rounded} ${
icon && !text ? "p-[10px]" : padding
} transition-all duration-300 ease-in-out text-s pointer-events-auto flex gap-1 items-center align-middle h-fit ${backgroundColor} ${textColor} ${border} ${
className ? className : ""
@@ -230,7 +230,6 @@ const SequenceWing = () => {
>
{/* Подписи Крылья */}
<svg
className="absolute top-0 z-[999]"
y={641}
x={818}
width="66"
@@ -239,12 +238,21 @@ const SequenceWing = () => {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="66" height="18" rx="9" fill="white" />
<g filter="url(#filter0_b_654_8218)">
<rect
width="66"
height="18"
rx="9"
fill="#0D1922"
fillOpacity="0.4"
/>
<path
d="M13.95 13H8.73V5.32H13.88V6.47H10.14V8.56H13.4V9.7H10.14V11.85H13.95V13ZM19.3193 13H18.0493L18.0193 12.24H17.9993C17.6893 12.78 17.1593 13.11 16.4293 13.11C15.3993 13.11 14.7193 12.43 14.7193 11.48C14.7193 10.82 15.0393 10.32 15.7393 10.08C16.2893 9.89 17.1293 9.84 17.9793 9.81V9.41C17.9793 8.92 17.6393 8.56 17.0093 8.56C16.4293 8.56 16.0893 8.85 15.9293 9.27L14.8893 8.76C15.2493 7.94 15.9793 7.52 17.0693 7.52C18.5193 7.52 19.3193 8.23 19.3193 9.41V13ZM16.8593 12.1C17.5393 12.1 17.9793 11.59 17.9793 10.96V10.67C17.6593 10.69 17.2093 10.72 16.8493 10.77C16.4193 10.83 16.0593 10.98 16.0593 11.42C16.0593 11.81 16.3493 12.1 16.8593 12.1ZM22.602 13.11C21.562 13.11 20.772 12.83 20.172 12.39L20.812 11.47C21.332 11.88 21.992 12.1 22.622 12.1C23.292 12.1 23.672 11.9 23.672 11.52C23.672 11.09 23.182 10.99 22.302 10.83C21.242 10.63 20.392 10.24 20.392 9.2C20.392 8.28 21.122 7.52 22.642 7.52C23.612 7.52 24.312 7.78 24.892 8.19L24.292 9.09C23.772 8.72 23.182 8.53 22.622 8.53C22.022 8.53 21.742 8.77 21.742 9.06C21.742 9.46 22.132 9.55 23.042 9.72C24.032 9.91 25.012 10.23 25.012 11.34C25.012 12.39 24.142 13.11 22.602 13.11ZM25.3252 8.61V7.63H26.3352V5.93H27.6752V7.63H28.8952V8.61H27.6752V11.25C27.6752 11.79 27.8352 12.06 28.4952 12.06C28.6452 12.06 28.7852 12.05 28.8952 12.03V13.01C28.6652 13.07 28.3452 13.11 28.0052 13.11C26.8552 13.11 26.3352 12.54 26.3352 11.54V8.61H25.3252ZM41.0123 5.32H42.4523L40.2523 13H38.6823L37.1123 7.32H37.0923L35.5223 13H33.9323L31.7223 5.32H33.2123L34.7923 11.25H34.8123L36.3523 5.32H37.9023L39.4423 11.22H39.4623L41.0123 5.32ZM43.1915 6.55V5.32H44.6015V6.55H43.1915ZM44.5715 13H43.2215V7.63H44.5715V13ZM45.9754 13V7.63H47.2454L47.2754 8.39H47.2954C47.6254 7.85 48.2054 7.52 48.9354 7.52C50.0654 7.52 50.7954 8.26 50.7954 9.37V13H49.4454V9.57C49.4454 9.02 49.1154 8.58 48.4854 8.58C47.7654 8.58 47.3254 9.09 47.3254 9.77V13H45.9754ZM57.0566 7.63V12.34C57.0566 14.1 55.8866 14.94 54.1366 14.94C53.2566 14.94 52.5866 14.72 52.1066 14.45L52.5466 13.47C52.9466 13.71 53.4366 13.93 54.1066 13.93C55.0166 13.93 55.7166 13.51 55.7166 12.38V12.01H55.6966C55.3166 12.55 54.7366 12.86 54.0166 12.86C52.6566 12.86 51.7866 11.73 51.7866 10.24C51.7866 8.75 52.6666 7.52 54.0966 7.52C54.8366 7.52 55.3966 7.86 55.7866 8.4H55.8066L55.8466 7.63H57.0566ZM54.4566 11.84C55.2966 11.84 55.7566 11.12 55.7566 10.19C55.7566 9.26 55.2866 8.56 54.4566 8.56C53.5866 8.56 53.1566 9.3 53.1566 10.21C53.1566 11.08 53.5666 11.84 54.4566 11.84Z"
fill="#0D1922"
fill="white"
/>
</g>
</svg>
<svg
y={641}
x={1067}
@@ -254,11 +262,19 @@ const SequenceWing = () => {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="71" height="18" rx="9" fill="white" />
<g filter="url(#filter0_b_654_8217)">
<rect
width="71"
height="18"
rx="9"
fill="#0D1922"
fillOpacity="0.4"
/>
<path
d="M17.36 5.32H18.8L16.6 13H15.03L13.46 7.32H13.44L11.87 13H10.28L8.07 5.32H9.56L11.14 11.25H11.16L12.7 5.32H14.25L15.79 11.22H15.81L17.36 5.32ZM20.1695 9.84H22.5995C22.5395 9.08 22.2095 8.55 21.4195 8.55C20.6395 8.55 20.2495 9.07 20.1695 9.84ZM22.8895 11.43L23.7495 12.19C23.2695 12.76 22.5795 13.11 21.5695 13.11C19.7495 13.11 18.7895 11.99 18.7895 10.32C18.7895 8.7 19.7395 7.52 21.4295 7.52C23.0995 7.52 23.9395 8.67 23.9395 10.15C23.9395 10.35 23.9295 10.6 23.8995 10.75H20.1695C20.2695 11.57 20.7095 12.08 21.5995 12.08C22.1195 12.08 22.5595 11.87 22.8895 11.43ZM26.8891 13.11C25.8491 13.11 25.0591 12.83 24.4591 12.39L25.0991 11.47C25.6191 11.88 26.2791 12.1 26.9091 12.1C27.5791 12.1 27.9591 11.9 27.9591 11.52C27.9591 11.09 27.4691 10.99 26.5891 10.83C25.5291 10.63 24.6791 10.24 24.6791 9.2C24.6791 8.28 25.4091 7.52 26.9291 7.52C27.8991 7.52 28.5991 7.78 29.1791 8.19L28.5791 9.09C28.0591 8.72 27.4691 8.53 26.9091 8.53C26.3091 8.53 26.0291 8.77 26.0291 9.06C26.0291 9.46 26.4191 9.55 27.3291 9.72C28.3191 9.91 29.2991 10.23 29.2991 11.34C29.2991 12.39 28.4291 13.11 26.8891 13.11ZM29.6123 8.61V7.63H30.6223V5.93H31.9623V7.63H33.1823V8.61H31.9623V11.25C31.9623 11.79 32.1223 12.06 32.7823 12.06C32.9323 12.06 33.0723 12.05 33.1823 12.03V13.01C32.9523 13.07 32.6323 13.11 32.2923 13.11C31.1423 13.11 30.6223 12.54 30.6223 11.54V8.61H29.6123ZM45.2995 5.32H46.7395L44.5395 13H42.9695L41.3995 7.32H41.3795L39.8095 13H38.2195L36.0095 5.32H37.4995L39.0795 11.25H39.0995L40.6395 5.32H42.1895L43.7295 11.22H43.7495L45.2995 5.32ZM47.4786 6.55V5.32H48.8886V6.55H47.4786ZM48.8586 13H47.5086V7.63H48.8586V13ZM50.2625 13V7.63H51.5325L51.5625 8.39H51.5825C51.9125 7.85 52.4925 7.52 53.2225 7.52C54.3525 7.52 55.0825 8.26 55.0825 9.37V13H53.7325V9.57C53.7325 9.02 53.4025 8.58 52.7725 8.58C52.0525 8.58 51.6125 9.09 51.6125 9.77V13H50.2625ZM61.3437 7.63V12.34C61.3437 14.1 60.1737 14.94 58.4237 14.94C57.5437 14.94 56.8737 14.72 56.3937 14.45L56.8337 13.47C57.2337 13.71 57.7237 13.93 58.3937 13.93C59.3037 13.93 60.0037 13.51 60.0037 12.38V12.01H59.9837C59.6037 12.55 59.0237 12.86 58.3037 12.86C56.9437 12.86 56.0737 11.73 56.0737 10.24C56.0737 8.75 56.9537 7.52 58.3837 7.52C59.1237 7.52 59.6837 7.86 60.0737 8.4H60.0937L60.1337 7.63H61.3437ZM58.7437 11.84C59.5837 11.84 60.0437 11.12 60.0437 10.19C60.0437 9.26 59.5737 8.56 58.7437 8.56C57.8737 8.56 57.4437 9.3 57.4437 10.21C57.4437 11.08 57.8537 11.84 58.7437 11.84Z"
fill="#0D1922"
fill="white"
/>
</g>
</svg>
{/* Этажи */}
@@ -270,9 +286,6 @@ const SequenceWing = () => {
viewBox="0 0 523 576"
fill="none"
xmlns="http://www.w3.org/2000/svg"
// onMouseLeave={handleOnFloorMouseLeave}
// onMouseOut={handleOnFloorMouseLeave}
onMouseOut={handleOnWingWrapperMouseLeave}
onMouseOver={handleOnWingWrapperMouseEnter}
className="opacity-0 absolute z-0"
@@ -37,7 +37,11 @@ const FavoriteAppartmentCard = ({ card }: FavoriteAppartmentCardProps) => {
</p>
</div>
</div>
<Button buttonType="favorite" icon={<HeartIcon isFilled />} />
<Button
buttonType="favorite"
icon={<HeartIcon isFilled />}
isCircleRounded
/>
</div>
<div className="w-full aspect-square rounded-lg">
<img src="/images/layout-1.png" alt="" className="h-full" />
+2 -2
View File
@@ -6,8 +6,8 @@ interface AuthProps {
isAuth?: boolean;
}
const Auth = ({ isAuth = false }: AuthProps) => {
const userName = "Name";
const Auth = ({ isAuth = true }: AuthProps) => {
const userName = "Full Name";
return (
<>
+8 -2
View File
@@ -10,9 +10,15 @@ const AuthDesktop = ({ isAuth, userName }: AuthProps) => {
<div className="flex gap-4 py-2 pr-6 text-black col-span-2 justify-end text-s">
{isAuth ? (
<>
<p>{userName}</p>
<div className="rounded-full w-10 h-10 bg-[#E2E2DC] overflow-clip">
<div>
<p className="">{userName}</p>
<p className="text-[#0D192266] text-caption-m font-semibold">
Company
</p>
</div>
<div className="rounded-full w-10 h-10 bg-[#E2E2DC] overflow-clip flex items-center justify-center font-semibold">
{/* <img src="" alt="avatar" className="bg-[#E2E2DC]" /> */}
FN
</div>
</>
) : (
+21
View File
@@ -0,0 +1,21 @@
const UnzoomIcon = () => {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M13.3335 8C13.3335 7.72386 13.1096 7.5 12.8335 7.5H3.16683C2.89069 7.5 2.66683 7.72386 2.66683 8C2.66683 8.27614 2.89069 8.5 3.16683 8.5H12.8335C13.1096 8.5 13.3335 8.27614 13.3335 8Z"
fill="#0D1922"
fillOpacity="0.7"
/>
</svg>
);
};
export default UnzoomIcon;
+19
View File
@@ -0,0 +1,19 @@
const ZoomIcon = () => {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M13.3332 7.99991C13.3332 7.71354 13.101 7.48139 12.8147 7.48139H8.51848V3.18502C8.51848 2.89865 8.28633 2.6665 7.99996 2.6665C7.71359 2.6665 7.48144 2.89865 7.48144 3.18502V7.48139H3.18502C2.89865 7.48139 2.6665 7.71354 2.6665 7.99991C2.6665 8.28628 2.89865 8.51842 3.18502 8.51842H7.48144L7.48144 12.8147C7.48144 13.101 7.71359 13.3332 7.99996 13.3332C8.28633 13.3332 8.51848 13.101 8.51848 12.8147L8.51848 8.51842H12.8147C13.101 8.51842 13.3332 8.28628 13.3332 7.99991Z"
fill="#0D1922"
fillOpacity="0.7"
/>
</svg>
);
};
export default ZoomIcon;
@@ -38,18 +38,21 @@ const TopPanel = () => {
buttonType="fab"
icon={<ActiveResizeIcon />}
onClick={handleOnFullScreenClick}
isCircleRounded
/>
) : (
<Button
buttonType="fab"
icon={<ResizeIcon />}
onClick={handleOnFullScreenClick}
isCircleRounded
/>
)}
<Button
buttonType="fab"
icon={<HintIcon />}
onClick={handleOnHelpClick}
isCircleRounded
/>
</div>
</>
+16 -12
View File
@@ -4,9 +4,11 @@ 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,
@@ -16,24 +18,25 @@ const Map = () => {
});
return (
<div className="relative">
<TransformWrapper
initialScale={isMobile ? 2 : 1}
minScale={isMobile ? 2 : 1}
alignmentAnimation={{ sizeX: 50, sizeY: 50 }}
wheel={{ step: 2 }}
// zoomAnimation={{
// disabled: false,
// size: 0,
// animationType: "easeOutQuart",
// animationTime: 500,
// }}
// velocityAnimation={{
// sensitivity: 1000,
// animationTime: 1000,
// animationType: "easeOut",
// }}
zoomAnimation={{
disabled: false,
size: 0,
animationType: "easeOutQuart",
animationTime: 500,
}}
velocityAnimation={{
sensitivity: 1000,
animationTime: 1000,
animationType: "easeOut",
}}
>
<ZoomControlls />
<TransformComponent
wrapperStyle={{
width: "calc(100vw + 400px)",
@@ -51,6 +54,7 @@ const Map = () => {
/>
</TransformComponent>
</TransformWrapper>
</div>
);
};
+6 -18
View File
@@ -1,14 +1,12 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { MarkerComponentProps } from "react-image-marker";
import { useEffect, useState } from "react";
import { useTransformContext } from "react-zoom-pan-pinch";
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 { transformState } = useTransformContext();
const [markerScale, setMarkerScale] = useState(1);
const navigate = useNavigate();
const currentMarker = markers.find(
@@ -20,11 +18,6 @@ const Marker = (props: MarkerComponentProps) => {
setHoveredMarker(hoveredMarker);
};
const handleOnScroll = () => {
const scale = 1 / transformState.scale;
setMarkerScale(scale);
};
const handleOnMouseLeave = () => {
setHoveredMarker(null);
};
@@ -34,15 +27,10 @@ const Marker = (props: MarkerComponentProps) => {
setHoveredMarker(null);
};
useEffect(() => {
const map = document.querySelector(".react-transform-wrapper");
handleOnScroll();
if (map) map.addEventListener("wheel", handleOnScroll);
return () => {
if (map) map.removeEventListener("wheel", handleOnScroll);
};
}, []);
useTransformEffect(({ state }) => {
const scale = 1 / state.scale;
setMarkerScale(scale);
});
return (
<div
@@ -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;
+2 -2
View File
@@ -65,8 +65,8 @@ const MasterplanFilters = () => {
};
return (
<div className="absolute z-50 top-0 left-0 w-screen bg-[#0D192266] h-screen backdrop-blur-[6px] grid grid-cols-12 items-center ">
<div className="h-full col-span-3 bg-[#F3F3F2] flex flex-col items-center justify-between ">
<div className="absolute z-50 top-0 left-0 w-screen bg-[#0D192266] h-screen backdrop-blur-[6px] items-center ">
<div className="h-full bg-[#F3F3F2] flex flex-col items-center justify-between w-[360px]">
<div className="w-full py-6 px-6 flex flex-col items-center">
<div className="flex justify-between border-b border-[#E2E2DC] w-full pb-4">
<h2 className="text-subheadline-m font-semibold">Filters</h2>
@@ -25,7 +25,7 @@ const ButtonPanel = () => {
</h2>
</div>
</div>
<Button buttonType="favorite" icon={<HeartIcon />} />
<Button buttonType="favorite" icon={<HeartIcon />} isCircleRounded />
</div>
);
};
@@ -47,12 +47,14 @@ const SimilarSlider = () => {
</h2>
<div className="flex gap-2">
<Button
isCircleRounded
onClick={handleOnLeftBtnClick}
icon={<RightArrowIcon />}
buttonType="fab"
className="rotate-180"
/>
<Button
isCircleRounded
icon={<RightArrowIcon />}
onClick={handleOnRightBtnClick}
buttonType="fab"
@@ -83,6 +83,7 @@ const SidebarFilters = () => {
<div className="flex justify-between border-b border-[#E2E2DC] w-full pb-4">
<h2 className="text-subheadline-m font-semibold">Filters</h2>
<Button
isCircleRounded
icon={<ResetIcon />}
buttonType="fab"
onClick={handleOnResetClick}
@@ -25,7 +25,11 @@ const ApartmentCard = () => {
<p className="text-caption-m font-semibold leading-4"> 213</p>
</div>
</div>
<Button icon={<HeartIcon isFilled={false} />} buttonType="favorite" />
<Button
icon={<HeartIcon isFilled={false} />}
buttonType="favorite"
isCircleRounded
/>
</div>
<div className="w-full aspect-square rounded-lg">
<img src="/images/layout-1.png" alt="" className="h-full" />
@@ -0,0 +1,43 @@
import useCompass from "../../store/useCompass";
import useModal from "../../store/useModal";
import Button from "../Button";
import DisclaimerIcon from "../icons/DisclaimerIcon";
import DisclaimerModal from "../modals/DisclaimerModal";
const ButtomPanelCompassVirtualTour = () => {
const { setModal } = useModal();
const { currentCompassRotate } = useCompass();
const handleOnDisclaimerClick = () => {
setModal(<DisclaimerModal />);
};
return (
<div className="absolute z-20 bottom-0 left-0 w-full select-none touch-none pointer-events-none flex gap-2 justify-between items-end">
<div className="flex flex-col gap-2">
<div className="flex gap-2 pb-6 pl-6">
<Button
text="Disclaimer"
buttonType="special"
className="pl-2"
icon={<DisclaimerIcon />}
onClick={handleOnDisclaimerClick}
/>
<Button text="Privacy Policy" buttonType="special" />
</div>
</div>
<div className="p-6">
<div className="bg-[#0D192266] rounded-full backdrop-blur-sm">
<img
style={{ transform: `rotate(${currentCompassRotate - 180}deg)` }}
src="/images/masterplan/compass.png"
alt="compass"
className=""
/>
</div>
</div>
</div>
);
};
export default ButtomPanelCompassVirtualTour;
@@ -0,0 +1,130 @@
import { useState } from "react";
import useSphere from "../../store/useSphere";
import { IAppartmentSphere, ISphere } from "../../types/apartmentSphere";
import Button from "../Button";
import BookingIcon from "../icons/BookingIcon";
import ChevronDownIcon from "../icons/ChevronDownIcon";
import HeartIcon from "../icons/Heart";
interface VirtualTourSidebarProps {
currentAppartment: null | IAppartmentSphere;
}
const VirtualTourSidebar = ({ currentAppartment }: VirtualTourSidebarProps) => {
const [isActive, setIsActive] = useState(false);
const { setSelectedSphere } = useSphere();
const handleOnShowClick = () => {
setIsActive((prev) => !prev);
};
const handleOnLabelClick = (sphere: ISphere) => {
setSelectedSphere(sphere);
};
return (
<div className="absolute w-screen h-screen grid z-[99999999] pointer-events-none">
<div className="h-screen py-[130px] px-3 w-[360px]">
<div className="bg-white w-full rounded-lg p-5 flex flex-col relative rounded-ee-none">
<div className="flex flex-col gap-1 pb-[18px] border-b">
<p className="text-[#00BED7] text-caption-m font-medium">
Rove Home Marasi Drive{" "}
</p>
<div className="text-[#73787C] flex gap-2 items-center w-fit">
<p className="text-caption-m font-semibold leading-4">
East Wing
</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p className="text-caption-m font-semibold leading-4">Floor 11</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p className="text-caption-m font-semibold leading-4"> 213</p>
</div>
</div>
<div className="pt-3">
<div className="flex gap-2 items-center">
<div className="bg-[#00BED7] py-[3px] px-2 rounded-full text-white text-caption-m flex items-center h-[22px]">
234
</div>
<p className="text-[#0D1922] font-semibold text-subheadline-s leading-6">
1 bedroom appartment
</p>
</div>
<div
className={`transition-all duration-700 ease-in-out ${
!isActive ? "max-h-0 opacity-0" : "max-h-screen opacity-100"
}`}
>
<div className="aspect-square w-full bg-black my-4"></div>
<div className="pt-4 border-t">
<div className="flex flex-col gap-3">
<div className="flex justify-between text-m">
<p className="text-[#73787C]">Size</p>
<p className="text-[#0D1922]">609 Sqft</p>
</div>
<div className="flex justify-between text-m">
<p className="text-[#73787C]">Status</p>
<p className="text-[#0D1922]">Available</p>
</div>
</div>
</div>
</div>
<div className="flex gap-2 pt-6">
<Button
icon={<BookingIcon />}
text="Send Enquiry"
buttonType="cta"
className="flex-1 flex items-center justify-center"
/>
<Button icon={<HeartIcon />} buttonType="secondary" />
</div>
</div>
<div className="h-14 absolute -bottom-14 left-0 w-full flex justify-between">
<div className="flex gap-1 py-2 items-start flex-wrap">
{currentAppartment &&
currentAppartment.spheres.map((sphere) => {
return (
<div
onClick={() => handleOnLabelClick(sphere)}
className="bg-[#F3F3F2] font-semibold text-[#0D1922] text-caption-s py-0.5 px-2 w-fit rounded-full cursor-pointer pointer-events-auto select-none"
key={sphere.id}
>
{sphere.roomType}
</div>
);
})}
</div>
<div className="transition-all duration-300 bg-[#FFFFFFCC] px-4 py-3 w-fit h-12 rounded-ee-lg rounded-es-lg select-none cursor-pointer pointer-events-auto items-start border border-t-[#0D1922B2] active:border-[#00BED7] hover:bg-[#FFFFFF] text-[#0D1922B2] hover:text-[#0D1922]">
<div
className="flex justify-center items-center gap-2"
onClick={handleOnShowClick}
>
<div className="relative">
<div
className={`transition-opacity duration-300 ${
!isActive ? "opacity-100" : "opacity-0"
}`}
>
Show
</div>
<div
className={`transition-opacity duration-300 absolute top-0 ${
!isActive ? "opacity-0" : "opacity-100"
}`}
>
Hide
</div>
</div>
<ChevronDownIcon
className={`transition-all duration-300 ${
!isActive ? "rotate-0" : "rotate-180"
}`}
/>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default VirtualTourSidebar;
@@ -41,11 +41,11 @@ const VirtualTourTopPanel = () => {
return (
<>
<div className="absolute top-0 w-screen z-20 select-none pointer-events-none">
<div className="absolute top-0 w-screen z-[99999999] select-none pointer-events-none">
<img src="../images/top_shadow.png" className="w-screen" alt="" />
</div>
<div
className={`absolute top-[62px] left-0 z-20 w-full p-4 grid grid-cols-12 select-none touch-none pointer-events-none`}
className={`absolute top-[62px] left-0 z-[99999999] w-full p-4 grid grid-cols-12 select-none touch-none pointer-events-none`}
>
<div className="flex gap-2 col-span-5">
<Button
@@ -6,7 +6,6 @@ import SphereTour from "./SphereTour";
import { IAppartmentSphere } from "../../types/apartmentSphere";
import useSphere from "../../store/useSphere";
import LabelMarker from "./LabelMarker";
// import { spheres } from "../../consts/spheres";
interface VirtualTourWrapperProps {
appartment: IAppartmentSphere;
+3 -3
View File
@@ -21,9 +21,9 @@ const textColors: ButtonStyle = {
};
const borders: ButtonStyle = {
cta: "rounded-lg",
primary: "rounded-lg border border-[#ffffff] active:border-[#00BED7]",
secondary: "rounded-lg border border-[#E2E2DC] active:border-[#00BED7]",
cta: "",
primary: "border border-[#ffffff] active:border-[#00BED7]",
secondary: " border border-[#E2E2DC] active:border-[#00BED7]",
tertiary: "",
fab: "rounded-full",
favorite: "rounded-full border border-[#E2E2DC]",
+7 -7
View File
@@ -1,7 +1,7 @@
[
{
"id": "studio-1_sp-01",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-01.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-01.jpg",
"roomType": "room 1",
"position": [-14.16, 0, 24.11],
"links": [
@@ -14,42 +14,42 @@
},
{
"id": "studio-1_sp-02",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-02.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-02.jpg",
"roomType": "room 2",
"position": [-14.16, 0, 24.11],
"links": []
},
{
"id": "studio-1_sp-03",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-03.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-03.jpg",
"roomType": "room 3",
"position": [-14.16, 0, 24.11],
"links": []
},
{
"id": "studio-1_sp-04",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-04.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-04.jpg",
"roomType": "room 4",
"position": [-14.16, 0, 24.11],
"links": []
},
{
"id": "studio-1_sp-05",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-05.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-05.jpg",
"roomType": "room 5",
"position": [-14.16, 0, 24.11],
"links": []
},
{
"id": "studio-1_sp-06",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-06.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-06.jpg",
"roomType": "room 6",
"position": [-14.16, 0, 24.11],
"links": []
},
{
"id": "studio-1_sp-07",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-07.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-07.jpg",
"roomType": "room 7",
"position": [-14.16, 0, 24.11],
"links": []
@@ -4,7 +4,7 @@
"spheres": [
{
"id": "studio-1_sp-01",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-01.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-01.jpg",
"roomType": "room 1",
"position": [-14.16, 0, 24.11],
"links": [
@@ -22,7 +22,7 @@
},
{
"id": "studio-1_sp-02",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-02.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-02.jpg",
"roomType": "room 2",
"position": [-14.16, 0, 24.11],
"links": [
@@ -35,7 +35,7 @@
},
{
"id": "studio-1_sp-03",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-03.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-03.jpg",
"roomType": "room 3",
"position": [-14.16, 0, 24.11],
"links": [
@@ -53,7 +53,7 @@
},
{
"id": "studio-1_sp-04",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-04.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-04.jpg",
"roomType": "room 4",
"position": [-14.16, 0, 24.11],
"links": [
@@ -71,7 +71,7 @@
},
{
"id": "studio-1_sp-05",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-05.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-05.jpg",
"roomType": "room 5",
"position": [-14.16, 0, 24.11],
"links": [
@@ -89,7 +89,7 @@
},
{
"id": "studio-1_sp-06",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-06.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-06.jpg",
"roomType": "room 6",
"position": [-14.16, 0, 24.11],
"links": [
@@ -107,7 +107,7 @@
},
{
"id": "studio-1_sp-07",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-07.webp",
"sphereImage": "/images/virtual-tour/studio1/Studio1_w-12_13_sp-07.jpg",
"roomType": "room 7",
"position": [-14.16, 0, 24.11],
"links": [
+8 -126
View File
@@ -1,36 +1,21 @@
import { useEffect, useState } from "react";
import { Canvas } from "@react-three/fiber";
import VirtualTourWrapper from "../components/virtualTour/VirtualTourWrapper";
import Button from "../components/Button";
import HeartIcon from "../components/icons/Heart";
import ChevronDownIcon from "../components/icons/ChevronDownIcon";
import ButtomPanelCompass from "../components/ButtomPanelCompass";
import BookingIcon from "../components/icons/BookingIcon";
import { IAppartmentSphere, ISphere } from "../types/apartmentSphere";
import useSphere from "../store/useSphere";
import { useParams } from "react-router-dom";
import _appartment from "../data/appartment.json";
import ButtonPanel from "../components/searchApartment/ButtonPanel";
import TopPanel from "../components/masterplanPage/TopPanel";
import VirtualTourWrapper from "../components/virtualTour/VirtualTourWrapper";
import { IAppartmentSphere } from "../types/apartmentSphere";
import _appartment from "../data/appartments.json";
import VirtualTourTopPanel from "../components/virtualTour/VirtualTourTopPanel";
import ButtomPanelCompassVirtualTour from "../components/virtualTour/ButtomPanelCompassVirualTour";
import VirtualTourSidebar from "../components/virtualTour/VirtualTourSidebar";
const appartments = _appartment as IAppartmentSphere[];
const VirtualTour = () => {
const [isActive, setIsActive] = useState(false);
const [currentAppartment, setCurrentAppartment] =
useState<null | IAppartmentSphere>(null);
const { setSelectedSphere } = useSphere();
const { appartmentTypeId } = useParams();
const handleOnShowClick = () => {
setIsActive((prev) => !prev);
};
const handleOnLabelClick = (sphere: ISphere) => {
setSelectedSphere(sphere);
};
useEffect(() => {
const _currentAppartment = appartments.find(
(app) => app.id === appartmentTypeId
@@ -43,116 +28,13 @@ const VirtualTour = () => {
return (
<div className="overflow-hidden h-screen w-screen">
<VirtualTourTopPanel />
<div className="absolute w-screen h-screen grid grid-cols-12 z-[99999999] pointer-events-none">
<div className="col-span-3 h-screen py-[130px] px-3">
<div className="bg-white w-full rounded-lg p-5 flex flex-col relative rounded-ee-none">
<div className="flex flex-col gap-1 pb-[18px] border-b">
<p className="text-[#00BED7] text-caption-m font-medium">
Rove Home Marasi Drive{" "}
</p>
<div className="text-[#73787C] flex gap-2 items-center w-fit">
<p className="text-caption-m font-semibold leading-4">
East Wing
</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p className="text-caption-m font-semibold leading-4">
Floor 11
</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p className="text-caption-m font-semibold leading-4"> 213</p>
</div>
</div>
<div className="pt-3">
<div className="flex gap-2 items-center">
<div className="bg-[#00BED7] py-[3px] px-2 rounded-full text-white text-caption-m flex items-center h-[22px]">
234
</div>
<p className="text-[#0D1922] font-semibold text-subheadline-s">
1 bedroom appartment
</p>
</div>
<div
className={`transition-all duration-700 ease-in-out ${
!isActive ? "max-h-0 opacity-0" : "max-h-screen opacity-100"
}`}
>
<div className="aspect-square w-full bg-black my-4"></div>
<div className="pt-4 border-t">
<div className="flex flex-col gap-3">
<div className="flex justify-between text-m">
<p className="text-[#73787C]">Size</p>
<p className="text-[#0D1922]">609 Sqft</p>
</div>
<div className="flex justify-between text-m">
<p className="text-[#73787C]">Status</p>
<p className="text-[#0D1922]">Available</p>
</div>
</div>
</div>
</div>
<div className="flex gap-2 pt-6">
<Button
icon={<BookingIcon />}
text="Send Enquiry"
buttonType="cta"
className="flex-1 flex items-center justify-center"
/>
<Button icon={<HeartIcon />} buttonType="secondary" />
</div>
</div>
<div className="h-14 absolute -bottom-14 left-0 w-full flex justify-between">
<div className="flex gap-1 py-2 items-start flex-wrap">
{currentAppartment &&
currentAppartment.spheres.map((sphere) => {
return (
<div
onClick={() => handleOnLabelClick(sphere)}
className="bg-[#F3F3F2] font-semibold text-[#0D1922] text-caption-s py-0.5 px-2 w-fit rounded-full cursor-pointer pointer-events-auto select-none"
key={sphere.id}
>
{sphere.roomType}
</div>
);
})}
</div>
<div className="transition-all duration-300 bg-[#FFFFFFCC] px-4 py-3 w-fit h-12 rounded-ee-lg rounded-es-lg select-none cursor-pointer pointer-events-auto items-start border border-t-[#0D1922B2] active:border-[#00BED7] hover:bg-[#FFFFFF] text-[#0D1922B2] hover:text-[#0D1922]">
<div
className="flex justify-center items-center gap-2"
onClick={handleOnShowClick}
>
<div className="relative">
<div
className={`transition-opacity duration-300 ${
!isActive ? "opacity-100" : "opacity-0"
}`}
>
Show
</div>
<div
className={`transition-opacity duration-300 absolute top-0 ${
!isActive ? "opacity-0" : "opacity-100"
}`}
>
Hide
</div>
</div>
<ChevronDownIcon
className={`transition-all duration-300 ${
!isActive ? "rotate-0" : "rotate-180"
}`}
/>
</div>
</div>
</div>
</div>
</div>
</div>
<VirtualTourSidebar currentAppartment={currentAppartment} />
<Canvas>
{currentAppartment && (
<VirtualTourWrapper appartment={currentAppartment} />
)}
</Canvas>
<ButtomPanelCompass />
<ButtomPanelCompassVirtualTour />
</div>
);
};