map + routing
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.9 MiB |
+7
-1
@@ -5,6 +5,7 @@ import { useVilla } from "./hooks/useVilla";
|
||||
import Desktop from "./pages/Desktop/Desktop";
|
||||
import Mobile from "./pages/Mobile/Mobile";
|
||||
import useStore from "./store/store";
|
||||
import { MapComponent } from "./components/Map/Map";
|
||||
|
||||
function App() {
|
||||
const { villa } = useVilla();
|
||||
@@ -14,7 +15,12 @@ function App() {
|
||||
setCurrentVilla(villa);
|
||||
}, [setCurrentVilla, villa]);
|
||||
|
||||
return <>{isMobile ? <Mobile /> : <Desktop />}</>;
|
||||
// return <>{isMobile ? <Mobile /> : <Desktop />}</>;
|
||||
return (
|
||||
<>
|
||||
<MapComponent />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import MapView from "@arcgis/core/views/MapView";
|
||||
import Map from "@arcgis/core/Map";
|
||||
|
||||
// import { createMapView } from "../../ArcGIS-SDK";
|
||||
|
||||
const createMapView = (container: HTMLDivElement) => {
|
||||
// const map = new Map({
|
||||
// // extent:esri.geometry.geographicToWebMercator(initExtent),
|
||||
// slider:false
|
||||
// });
|
||||
const map = new Map({
|
||||
basemap: "osm",
|
||||
// basemap: "osm",
|
||||
basemap: "streets",
|
||||
// ground: "world-elevation",
|
||||
// basemap: "terrain/base",
|
||||
});
|
||||
|
||||
return new MapView({
|
||||
map: map,
|
||||
container: container,
|
||||
center: [55, 25],
|
||||
center: [54.67, 24.33],
|
||||
zoom: 13,
|
||||
});
|
||||
};
|
||||
@@ -38,7 +47,7 @@ export const MapComponent = (props: IArcMapViewProps) => {
|
||||
return () => _view && _view.destroy();
|
||||
}, []);
|
||||
return (
|
||||
<div className="w-80 h-80" ref={mapRef}>
|
||||
<div className="w-screen h-screen" ref={mapRef}>
|
||||
<MapViewContext.Provider value={{ view }}>
|
||||
{children}
|
||||
</MapViewContext.Provider>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
const units = [
|
||||
{ id: 1, title: "Entrance", area: "3.25x3.10" },
|
||||
{ id: 2, title: "Living Room", area: "4.10x5.10" },
|
||||
{ id: 3, title: "Dining Room", area: "5.00x5.00" },
|
||||
{ id: 4, title: "Store 1", area: "2.90x1.35" },
|
||||
{ id: 5, title: "Men’s Majlas", area: "5.00x7.00" },
|
||||
{ id: 6, title: "Bathroom 1", area: "1.70x2.00" },
|
||||
{ id: 7, title: "Washbasins", area: "1.80x2.00" },
|
||||
{ id: 8, title: "Guest Bedroom", area: "4.10x4.60" },
|
||||
{ id: 9, title: "Bathroom 2", area: "2.70x2.00" },
|
||||
{ id: 10, title: "Kitchen", area: "5.00x4.00" },
|
||||
{ id: 11, title: "Bathroom 3", area: "1.50x2.50" },
|
||||
{ id: 12, title: "Store 2", area: "2.20x1.30" },
|
||||
{ id: 13, title: "Laundry Room", area: "2.20x1.50" },
|
||||
{ id: 14, title: "Domestic Worker Room", area: "3.50x3.00" },
|
||||
{ id: 15, title: "Domestic Worker Bathroom", area: "1.50x2.00" },
|
||||
];
|
||||
|
||||
const UnitList = () => {
|
||||
return (
|
||||
<div className="px-8 py-6">
|
||||
<div className="font-medium text-lg flex w-full gap-[18px] py-2 pr-6 pl-4 ">
|
||||
<div>№</div>
|
||||
<div className="flex justify-between w-full">
|
||||
<div>Unit</div>
|
||||
<div>Area (m)</div>
|
||||
</div>
|
||||
</div>
|
||||
{units.map((unit, index) => (
|
||||
<div
|
||||
key={unit.id}
|
||||
className={`font-medium text-lg flex w-full gap-[18px] py-2 pr-6 pl-4 ${
|
||||
index % 2 === 0 ? "bg-[#F3F2F0] rounded-lg" : ""
|
||||
}`}
|
||||
>
|
||||
<div>{index + 1}</div>
|
||||
<div className="flex justify-between w-full">
|
||||
<div>{unit.title}</div>
|
||||
<div>{unit.area}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UnitList;
|
||||
@@ -48,7 +48,7 @@ const ViewToggle = ({ offset, isDesktop }: ViewSwitcherProps) => {
|
||||
onClick={handleOnFirstClick}
|
||||
className={`${
|
||||
currentView === 1 ? "bg-black text-white" : ""
|
||||
} py-2 px-4 w-fit rounded-[32px] `}
|
||||
} py-2 px-4 w-fit rounded-[32px] `}
|
||||
>
|
||||
{" "}
|
||||
Outdoor
|
||||
|
||||
@@ -15,7 +15,7 @@ const Parameters = () => {
|
||||
</div>
|
||||
<div className="flex justify-between gap-4">
|
||||
<div className="w-1/2 text-sm text-[#666668] font-medium">
|
||||
Plot area
|
||||
Plot area m<sup>2</sup>
|
||||
</div>
|
||||
<div className="w-1/2 text-sm font-medium">
|
||||
{currentVilla && currentVilla.plotArea}
|
||||
@@ -23,7 +23,7 @@ const Parameters = () => {
|
||||
</div>
|
||||
<div className="flex justify-between gap-4">
|
||||
<div className="w-1/2 text-sm text-[#666668] font-medium">
|
||||
Total Build up Area
|
||||
Unit Area, m<sup>2</sup>
|
||||
</div>
|
||||
<div className="w-1/2 text-sm font-medium">
|
||||
{currentVilla && currentVilla.totalBuildUpArea}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { SwipeEventData, useSwipeable } from "react-swipeable";
|
||||
import ButtonSwipperIcon from "../../../icons/ButtonSwipperIcon";
|
||||
// import { Parameters as ParametersType } from "../../../types/appartment";
|
||||
import Parameters from "./Parameters";
|
||||
import LayoutSlider from "./LayoutSlider";
|
||||
import ImageSlider from "./ImageSlider";
|
||||
import ViewToggle from "../../ViewToggle";
|
||||
import UnitList from "../../UnitList";
|
||||
|
||||
const ViewControllerModal = () => {
|
||||
// const { sliders } = parameters;
|
||||
const [offset, setOffset] = useState(1);
|
||||
const [isActive, setIsActive] = useState(false);
|
||||
const [isTouchable, setIsTouchable] = useState(true);
|
||||
const [scrollY, setScrollY] = useState(0);
|
||||
|
||||
@@ -24,32 +25,48 @@ const ViewControllerModal = () => {
|
||||
const handleOnSwiped = (eventData: SwipeEventData) => {
|
||||
if (eventData.dir === "Down") {
|
||||
setOffset(1);
|
||||
setIsActive(false);
|
||||
}
|
||||
if (eventData.dir === "Up") {
|
||||
setOffset(0);
|
||||
setIsActive(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnBackClick = () => {
|
||||
setOffset(1);
|
||||
setIsActive(false);
|
||||
};
|
||||
|
||||
const handleOnScroll = (event: React.UIEvent<HTMLDivElement, UIEvent>) => {
|
||||
setScrollY(event.currentTarget.scrollTop);
|
||||
};
|
||||
|
||||
const handleOnSwiping = (eventData: SwipeEventData) => {
|
||||
const screenHeight = window.innerHeight;
|
||||
if (eventData.dir === "Down" && isActive && offset <= 1) {
|
||||
const offsetDown = eventData.absY / screenHeight;
|
||||
setOffset(() => offsetDown);
|
||||
}
|
||||
if (eventData.dir === "Up" && !isActive && offset >= 0) {
|
||||
const offsetDown = 1 - eventData.absY / screenHeight;
|
||||
setOffset(() => offsetDown);
|
||||
}
|
||||
};
|
||||
|
||||
const handlers = useSwipeable({
|
||||
onSwiped: handleOnSwiped,
|
||||
preventScrollOnSwipe: offset === 1,
|
||||
onSwiping: handleOnSwiping,
|
||||
|
||||
preventScrollOnSwipe: offset !== 0,
|
||||
trackTouch: isTouchable,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className=" flex flex-col fixed left-0 top-0 z-20 bg-black">
|
||||
<div className="flex flex-col fixed left-0 top-0 z-20" {...handlers}>
|
||||
<div
|
||||
{...handlers}
|
||||
className={`${
|
||||
offset === 1 ? "rounded-ss-2xl rounded-se-2xl" : ""
|
||||
isActive ? "rounded-ss-2xl rounded-se-2xl" : ""
|
||||
} bg-white w-full h-[calc(100vh)] border flex flex-col transition-all duration-500 fixed left-0 top-0 ease-in-out`}
|
||||
style={{
|
||||
transform: `translateY(calc(${offset * 80}vh))`,
|
||||
@@ -66,7 +83,9 @@ const ViewControllerModal = () => {
|
||||
<LayoutSlider />
|
||||
<Parameters />
|
||||
<ImageSlider />
|
||||
{/* <UnitList /> */}
|
||||
</div>
|
||||
|
||||
<div className="px-6 py-4 mt-auto border">
|
||||
<button
|
||||
className="border flex w-full py-3 justify-center rounded-full"
|
||||
|
||||
+38
-4
@@ -1,9 +1,9 @@
|
||||
import { Villa } from "../types/appartment";
|
||||
|
||||
const villaA1M: Villa = {
|
||||
type: "A1M",
|
||||
plotArea: "1080 Sq.m",
|
||||
totalBuildUpArea: "472 Sq.m",
|
||||
type: "a1m",
|
||||
plotArea: "1080",
|
||||
totalBuildUpArea: "461",
|
||||
totalCountBedroms: 5,
|
||||
villaTheme: "Modern",
|
||||
sliders: [
|
||||
@@ -32,6 +32,40 @@ const villaA1M: Villa = {
|
||||
],
|
||||
};
|
||||
|
||||
const villas =[villaA1M]
|
||||
const villaA1T: Villa = {
|
||||
type: "a1t",
|
||||
plotArea: "1080",
|
||||
totalBuildUpArea: "444",
|
||||
totalCountBedroms: 5,
|
||||
villaTheme: "Traditional",
|
||||
sliders: [
|
||||
{
|
||||
id: 1,
|
||||
image: "/images/apartment/A1T/A1T_GF.png",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
image: "/images/apartment/A1T/A1T_1F.png",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
image: "/images/apartment/A1T/A1T_P.png",
|
||||
},
|
||||
],
|
||||
perspectiveWorkings: [
|
||||
{
|
||||
id: 1,
|
||||
image: "/images/apartment/A1T/perspectiveWorking/001_Villa_A1TO_CAM_01_R05.jpg",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
image: "/images/apartment/A1T/perspectiveWorking/001_Villa_A1TO_CAM_02_R04.jpg",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
|
||||
const villas = [villaA1M,villaA1T]
|
||||
|
||||
export { villaA1M, villas };
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { useUnityContext } from "react-unity-webgl";
|
||||
|
||||
function useUnity() {
|
||||
return useUnityContext({
|
||||
loaderUrl: "builds/estate-webgl.loader.js",
|
||||
dataUrl: "builds/estate-webgl.data.unityweb",
|
||||
frameworkUrl: "builds/estate-webgl.framework.js.unityweb",
|
||||
codeUrl: "builds/estate-webgl.wasm.unityweb",
|
||||
streamingAssetsUrl: "StreamingAssets",
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export {useUnity}
|
||||
@@ -6,6 +6,10 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.esri-widget {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-family: "Noto Sans", sans-serif;
|
||||
|
||||
+4
-1
@@ -1,11 +1,14 @@
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
// import { HashRouter } from "react-router-dom";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: "/villa/:villaTitle",
|
||||
// path: "/villa",
|
||||
path: "/:villaTitle",
|
||||
// path: "/",
|
||||
element: <App />,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Unity, useUnityContext } from "react-unity-webgl";
|
||||
import { Unity } from "react-unity-webgl";
|
||||
import { useEffect } from "react";
|
||||
import { ReactUnityEventParameter } from "react-unity-webgl/distribution/types/react-unity-event-parameters";
|
||||
import useStore from "../../store/store";
|
||||
import LoaderModal from "../../components/LoaderModal";
|
||||
import ButtonPanel from "../../components/desktop/ButtonPanel";
|
||||
import ParameterDescription from "../../components/desktop/ParameterDescription";
|
||||
import LayoutsButtonContainer from "../../components/desktop/LayoutsButtonContainer";
|
||||
import { useUnity } from "../../hooks/useUnity";
|
||||
|
||||
const Desktop = () => {
|
||||
const { loader, setLoader, setSendMessageToUnity } = useStore();
|
||||
@@ -16,13 +16,7 @@ const Desktop = () => {
|
||||
sendMessage,
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
} = useUnityContext({
|
||||
loaderUrl: "builds/estate-webgl.loader.js",
|
||||
dataUrl: "builds/estate-webgl.data.unityweb",
|
||||
frameworkUrl: "builds/estate-webgl.framework.js.unityweb",
|
||||
codeUrl: "builds/estate-webgl.wasm.unityweb",
|
||||
streamingAssetsUrl: "StreamingAssets",
|
||||
});
|
||||
} = useUnity();
|
||||
|
||||
const handleSetLoaded = (isSceneLoaded: ReactUnityEventParameter) => {
|
||||
if (isSceneLoaded === 0) {
|
||||
@@ -60,7 +54,6 @@ const Desktop = () => {
|
||||
unityProvider={unityProvider}
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
/>
|
||||
<LayoutsButtonContainer />
|
||||
</div>
|
||||
<ParameterDescription />
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useEffect } from "react";
|
||||
import { ReactUnityEventParameter } from "react-unity-webgl/distribution/types/react-unity-event-parameters";
|
||||
import { Unity, useUnityContext } from "react-unity-webgl";
|
||||
import { Unity } from "react-unity-webgl";
|
||||
import useStore from "../../store/store";
|
||||
import LoaderModal from "../../components/LoaderModal";
|
||||
import ButtonPanel from "../../components/mobile/Appartment/ButtonPanel";
|
||||
import ViewControllerModal from "../../components/mobile/Appartment/ViewControllerModal";
|
||||
import { useUnity } from "../../hooks/useUnity";
|
||||
|
||||
const Mobile = () => {
|
||||
const {
|
||||
@@ -25,13 +26,7 @@ const Mobile = () => {
|
||||
sendMessage,
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
} = useUnityContext({
|
||||
loaderUrl: "builds/estate-webgl.loader.js",
|
||||
dataUrl: "builds/estate-webgl.data.unityweb",
|
||||
frameworkUrl: "builds/estate-webgl.framework.js.unityweb",
|
||||
codeUrl: "builds/estate-webgl.wasm.unityweb",
|
||||
streamingAssetsUrl: "StreamingAssets",
|
||||
});
|
||||
} = useUnity();
|
||||
|
||||
const handleSetLoaded = (isSceneLoaded: ReactUnityEventParameter) => {
|
||||
if (isSceneLoaded === 0) {
|
||||
@@ -43,7 +38,9 @@ const Mobile = () => {
|
||||
};
|
||||
|
||||
const handleSetView = (view: ReactUnityEventParameter) => {
|
||||
setCurrentView(view as number);
|
||||
if (view === 1 || view === 2 || view === 3) {
|
||||
setCurrentView(view);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user