bottom Panel

This commit is contained in:
2024-02-05 13:37:01 +05:00
parent 82299f1ea8
commit b6c4ea24b3
8 changed files with 139 additions and 154 deletions
+11 -1
View File
@@ -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
View File
@@ -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 -8
View File
@@ -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 />);
+2
View File
@@ -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,