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;
}