bottom Panel
This commit is contained in:
@@ -39,7 +39,17 @@ const createMapView = (container: HTMLDivElement) => {
|
||||
view.on("double-click", ["Control"], stopEvtPropagation);
|
||||
|
||||
// disables pinch-zoom and panning on the view
|
||||
view.on("drag", (e: any) => console.log("e", e));
|
||||
view.on("drag", (event: any) => {
|
||||
if (event.native) {
|
||||
// Check if the event is from a touch device
|
||||
const pointerCount = event.native.length;
|
||||
if (pointerCount === 2) {
|
||||
console.log("event.pointerMovePoints", event);
|
||||
// Use two-finger drag to move the map
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// disable the view's zoom box to prevent the Shift + drag
|
||||
// and Shift + Control + drag zoom gestures.
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import { useDrag } from "@use-gesture/react";
|
||||
import { a, useSpring, config } from "@react-spring/web";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import ButtonSwipperIcon from "../../../icons/ButtonSwipperIcon";
|
||||
import ViewToggle from "../../ViewToggle";
|
||||
import ImageSlider from "./ImageSlider";
|
||||
import LayoutSlider from "./LayoutSlider";
|
||||
import Parameters from "./Parameters";
|
||||
|
||||
export default function ButtomPanelModal() {
|
||||
const [height, setHeight] = useState(0);
|
||||
const [offset, setOffset] = useState(1);
|
||||
// const [scrollY, setScrollY] = useState(0);
|
||||
const [isTouchable, setIsTouchable] = useState(true);
|
||||
const [{ y }, api] = useSpring(() => ({ y: 0 }));
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setHeight(window.screen.height);
|
||||
}, []);
|
||||
|
||||
// useEffect(() => {}, []);
|
||||
|
||||
const handleOnScroll = (event: React.UIEvent<HTMLDivElement, UIEvent>) => {
|
||||
if (event.currentTarget.scrollTop > 0) {
|
||||
setIsTouchable(false);
|
||||
} else {
|
||||
setIsTouchable(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnClose = () => {
|
||||
setOffset(1);
|
||||
close();
|
||||
};
|
||||
|
||||
const open = ({ canceled }) => {
|
||||
api.start({
|
||||
y: 0,
|
||||
immediate: false,
|
||||
config: canceled ? config.wobbly : config.stiff,
|
||||
});
|
||||
};
|
||||
const close = (velocity = 0) => {
|
||||
api.start({
|
||||
y: height - 64,
|
||||
immediate: false,
|
||||
config: { ...config.stiff, velocity },
|
||||
});
|
||||
};
|
||||
|
||||
const bind = useDrag(
|
||||
({
|
||||
active,
|
||||
last,
|
||||
velocity: [, vy],
|
||||
direction: [, dy],
|
||||
offset: [, oy],
|
||||
cancel,
|
||||
canceled,
|
||||
}) => {
|
||||
if (oy < -10) cancel();
|
||||
|
||||
if (last) {
|
||||
if (oy > height * 0.8 || dy >= 0) {
|
||||
setOffset(1);
|
||||
|
||||
close(vy);
|
||||
}
|
||||
if (oy < height * 0.5 || (dy < 0 && vy > 0.2)) {
|
||||
setOffset(0);
|
||||
open({ canceled });
|
||||
}
|
||||
} else api.start({ y: oy, immediate: true });
|
||||
},
|
||||
{
|
||||
from: () => [0, y.get()],
|
||||
filterTaps: true,
|
||||
bounds: { top: 0 },
|
||||
rubberband: true,
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex overflow-hidden">
|
||||
<a.div
|
||||
className={`fixed h-[calc(100vh + 600px)] w-screen z-30 border bg-white touch-none ${
|
||||
offset === 1 ? "rounded-ss-2xl rounded-se-2xl " : ""
|
||||
}`}
|
||||
{...bind()}
|
||||
style={{ y }}
|
||||
>
|
||||
<ViewToggle offset={offset} />
|
||||
<div className="mx-auto flex justify-center self-start w-full">
|
||||
<ButtonSwipperIcon />
|
||||
</div>
|
||||
<div
|
||||
className={`h-[calc(100vh-110px)] overflow-y-scroll ${
|
||||
!isTouchable ? "" : "touch-pan-down"
|
||||
}`}
|
||||
onScroll={handleOnScroll}
|
||||
>
|
||||
<ImageSlider />
|
||||
<Parameters />
|
||||
<LayoutSlider />
|
||||
</div>
|
||||
|
||||
<div className="px-6 py-4 mt-auto border pb-14">
|
||||
<button
|
||||
className="border flex w-full py-3 justify-center rounded-full"
|
||||
onClick={handleOnClose}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</a.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import useStore from "../../../store/store";
|
||||
const ImageSlider = () => {
|
||||
const { currentVilla } = useStore();
|
||||
return (
|
||||
<div className="flex p-6 gap-2 overflow-x-scroll">
|
||||
<div className="flex p-6 gap-2 overflow-x-scroll touch-pan-x">
|
||||
{currentVilla &&
|
||||
currentVilla.perspectiveWorkings.map((working) => (
|
||||
<img
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
import { useDrag } from "@use-gesture/react";
|
||||
import { a, useSpring, config } from "@react-spring/web";
|
||||
import { useLayoutEffect, useState } from "react";
|
||||
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
const items = ["save item", "open item", "share item", "delete item", "cancel"];
|
||||
// const height = items.length * 60 + 80;
|
||||
|
||||
export default function ButtomPanel() {
|
||||
const [height, setHeight] = useState(0);
|
||||
useLayoutEffect(() => {
|
||||
setHeight(window.screen.height);
|
||||
}, []);
|
||||
|
||||
const [{ y }, api] = useSpring(() => ({ y: height }));
|
||||
|
||||
const open = ({ canceled }) => {
|
||||
// when cancel is true, it means that the user passed the upwards threshold
|
||||
// so we change the spring config to create a nice wobbly effect
|
||||
api.start({
|
||||
y: 0,
|
||||
immediate: false,
|
||||
config: canceled ? config.wobbly : config.stiff,
|
||||
});
|
||||
};
|
||||
const close = (velocity = 0) => {
|
||||
api.start({
|
||||
y: height - 64,
|
||||
immediate: false,
|
||||
config: { ...config.stiff, velocity },
|
||||
});
|
||||
};
|
||||
|
||||
const bind = useDrag(
|
||||
({
|
||||
last,
|
||||
velocity: [, vy],
|
||||
direction: [, dy],
|
||||
offset: [, oy],
|
||||
cancel,
|
||||
canceled,
|
||||
}) => {
|
||||
// if the user drags up passed a threshold, then we cancel
|
||||
// the drag so that the sheet resets to its open position
|
||||
if (oy < -10) cancel();
|
||||
|
||||
// when the user releases the sheet, we check whether it passed
|
||||
// the threshold for it to close, or if we reset it to its open positino
|
||||
if (last) {
|
||||
// oy > height * 0.8 || (vy > 0.8 && dy > 0)
|
||||
// ? close(vy)
|
||||
// : open({ canceled });
|
||||
console.log("oy", oy);
|
||||
if (oy > height * 0.8) {
|
||||
console.log("close");
|
||||
close(vy);
|
||||
}
|
||||
if (oy < height * 0.8) {
|
||||
console.log("open");
|
||||
open({ canceled });
|
||||
}
|
||||
// else {
|
||||
// }
|
||||
// if (oy > height * 0.2 || (vy > 0.5 && dy > 0)) {
|
||||
// console.log("close");
|
||||
// close(vy);
|
||||
// } else if ((vy > 0.5 && dy < 0) || oy < height * 0.2) {
|
||||
// console.log("open");
|
||||
// open({ canceled });
|
||||
// }
|
||||
// if (oy > height * 0.5 || (vy > 0.5 && dy > 0)) {
|
||||
// close(vy);
|
||||
// }
|
||||
// if (oy < height * 0.8) {
|
||||
// open({ canceled });
|
||||
// }
|
||||
}
|
||||
// when the user keeps dragging, we just move the sheet according to
|
||||
// the cursor position
|
||||
else api.start({ y: oy, immediate: true });
|
||||
},
|
||||
{
|
||||
from: () => [0, y.get()],
|
||||
filterTaps: true,
|
||||
bounds: { top: 0 },
|
||||
rubberband: true,
|
||||
}
|
||||
);
|
||||
|
||||
const display = y.to((py) => (py < height ? "block" : "none"));
|
||||
|
||||
return (
|
||||
<div className="flex" style={{ overflow: "hidden" }}>
|
||||
<a.div
|
||||
className={styles.sheet}
|
||||
{...bind()}
|
||||
style={{ display, y }} //
|
||||
>
|
||||
{items.map((entry, i) => (
|
||||
<div
|
||||
key={entry}
|
||||
onClick={() =>
|
||||
i < items.length - 1 ? alert("clicked on " + entry) : close()
|
||||
}
|
||||
children={entry}
|
||||
/>
|
||||
))}
|
||||
</a.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
.bg {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bg > img {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sheet {
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
height: calc(100vh + 100px);
|
||||
width: 100vw;
|
||||
border-radius: 12px 12px 0px;
|
||||
background: #fff;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.sheet > div {
|
||||
height: 60px;
|
||||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 20px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
+3
-3
@@ -4,7 +4,7 @@ import MainPage from "./pages/MainPage";
|
||||
import App from "./App";
|
||||
import "./index.css";
|
||||
import Layout from "./components/Layout";
|
||||
import ButtomPanel from "../src/components/mobile/Appartment/ViewControllerModal1";
|
||||
import ButtomPanelModal from "./components/mobile/Appartment/ButomPanelModal";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@@ -18,8 +18,8 @@ const router = createBrowserRouter([
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
// element: <MainPage />,
|
||||
element: <ButtomPanel />,
|
||||
element: <MainPage />,
|
||||
// element: <ButtomPanelModal />,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,10 +4,9 @@ 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";
|
||||
import { useVilla } from "../../hooks/useVilla";
|
||||
import BottomPanel from "../../components/mobile/Appartment/ViewControllerModal1";
|
||||
import ButtomPanelModal from "../../components/mobile/Appartment/ButomPanelModal";
|
||||
|
||||
const Mobile = () => {
|
||||
const {
|
||||
@@ -32,11 +31,10 @@ const Mobile = () => {
|
||||
} = useUnity();
|
||||
|
||||
const handleSetLoaded = (isSceneLoaded: ReactUnityEventParameter) => {
|
||||
if (isSceneLoaded === 0) {
|
||||
if (isSceneLoaded === 0 && isLoaded) {
|
||||
setLoader(<LoaderModal isSimleLoader />);
|
||||
} else {
|
||||
setModal(<ViewControllerModal />);
|
||||
|
||||
setModal(<ButtomPanelModal />);
|
||||
setLoader(null);
|
||||
}
|
||||
};
|
||||
@@ -63,15 +61,13 @@ const Mobile = () => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// setModal(<BottomPanel />);
|
||||
if (!isLoaded) {
|
||||
setLoader(<LoaderModal />);
|
||||
} else {
|
||||
setLoader(null);
|
||||
|
||||
setModal(<ButtomPanelModal />);
|
||||
setSendMessageToUnity(sendMessage);
|
||||
sendMessage("SceneContext", "SwitchLevel");
|
||||
setModal(<ViewControllerModal />);
|
||||
|
||||
if (is3DTour) {
|
||||
setPanel(<ButtonPanel />);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { create } from "zustand";
|
||||
import { ReactUnityEventParameter } from "react-unity-webgl/distribution/types/react-unity-event-parameters";
|
||||
import { Villa } from "../types/appartment";
|
||||
import { VILLAS } from "../consts/villas";
|
||||
|
||||
interface StoreType {
|
||||
currentVilla: Villa | null;
|
||||
@@ -23,6 +24,7 @@ interface StoreType {
|
||||
}
|
||||
|
||||
const useStore = create<StoreType>((set) => ({
|
||||
// currentVilla: VILLAS[0],
|
||||
currentVilla: null,
|
||||
is3DTour: false,
|
||||
selectedOnMapVilla: null,
|
||||
|
||||
Reference in New Issue
Block a user