change fab ui
This commit is contained in:
@@ -1,62 +1,36 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { limitNumber } from "../../libs/utils";
|
import { limitNumber } from "../../libs/utils";
|
||||||
import { isMobile } from "../../libs/mobile";
|
import { isMobile } from "../../libs/mobile";
|
||||||
import { setFab } from "../../libs/storage";
|
import { setFab } from "../../libs/storage";
|
||||||
|
import { debounce } from "../../libs/utils";
|
||||||
import Paper from "@mui/material/Paper";
|
import Paper from "@mui/material/Paper";
|
||||||
|
|
||||||
const getEdgePosition = (
|
const getEdgePosition = ({
|
||||||
{ x: left, y: top, edge },
|
x: left,
|
||||||
|
y: top,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
windowWidth,
|
windowWidth,
|
||||||
windowHeight,
|
windowHeight,
|
||||||
width,
|
hover,
|
||||||
height
|
}) => {
|
||||||
) => {
|
|
||||||
const right = windowWidth - left - width;
|
const right = windowWidth - left - width;
|
||||||
const bottom = windowHeight - top - height;
|
const bottom = windowHeight - top - height;
|
||||||
const min = Math.min(left, top, right, bottom);
|
const min = Math.min(left, top, right, bottom);
|
||||||
switch (min) {
|
switch (min) {
|
||||||
case right:
|
case right:
|
||||||
edge = "right";
|
left = hover ? windowWidth - width : windowWidth - width / 2;
|
||||||
left = windowWidth - width;
|
|
||||||
break;
|
break;
|
||||||
case left:
|
case left:
|
||||||
edge = "left";
|
left = hover ? 0 : -width / 2;
|
||||||
left = 0;
|
|
||||||
break;
|
break;
|
||||||
case bottom:
|
case bottom:
|
||||||
edge = "bottom";
|
top = hover ? windowHeight - height : windowHeight - height / 2;
|
||||||
top = windowHeight - height;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
edge = "top";
|
top = hover ? 0 : -height / 2;
|
||||||
top = 0;
|
|
||||||
}
|
}
|
||||||
left = limitNumber(left, 0, windowWidth - width);
|
return { x: left, y: top };
|
||||||
top = limitNumber(top, 0, windowHeight - height);
|
|
||||||
return { x: left, y: top, edge, hide: false };
|
|
||||||
};
|
|
||||||
|
|
||||||
const getHidePosition = (
|
|
||||||
{ x: left, y: top, edge },
|
|
||||||
windowWidth,
|
|
||||||
windowHeight,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
) => {
|
|
||||||
switch (edge) {
|
|
||||||
case "right":
|
|
||||||
left = windowWidth - width / 2;
|
|
||||||
break;
|
|
||||||
case "left":
|
|
||||||
left = -width / 2;
|
|
||||||
break;
|
|
||||||
case "bottom":
|
|
||||||
top = windowHeight - height / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
top = -height / 2;
|
|
||||||
}
|
|
||||||
return { x: left, y: top, edge, hide: true };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function DraggableWrapper({ children, usePaper, ...props }) {
|
function DraggableWrapper({ children, usePaper, ...props }) {
|
||||||
@@ -71,7 +45,7 @@ function DraggableWrapper({ children, usePaper, ...props }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Draggable({
|
export default function Draggable({
|
||||||
windowSize,
|
windowSize: { w: windowWidth, h: windowHeight },
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
left,
|
left,
|
||||||
@@ -84,65 +58,36 @@ export default function Draggable({
|
|||||||
children,
|
children,
|
||||||
usePaper,
|
usePaper,
|
||||||
}) {
|
}) {
|
||||||
const [origin, setOrigin] = useState({
|
const [hover, setHover] = useState(false);
|
||||||
x: left,
|
const [origin, setOrigin] = useState(null);
|
||||||
y: top,
|
const [position, setPosition] = useState({ x: left, y: top });
|
||||||
px: left,
|
const setFabPosition = useMemo(() => debounce(setFab, 500), []);
|
||||||
py: top,
|
|
||||||
});
|
|
||||||
const [position, setPosition] = useState({
|
|
||||||
x: left,
|
|
||||||
y: top,
|
|
||||||
edge: null,
|
|
||||||
hide: false,
|
|
||||||
});
|
|
||||||
const [edgeTimer, setEdgeTimer] = useState(null);
|
|
||||||
|
|
||||||
const goEdge = useCallback((w, h, width, height) => {
|
|
||||||
setPosition((pre) => getEdgePosition(pre, w, h, width, height));
|
|
||||||
|
|
||||||
setEdgeTimer(
|
|
||||||
setTimeout(() => {
|
|
||||||
setPosition((pre) => getHidePosition(pre, w, h, width, height));
|
|
||||||
}, 1500)
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handlePointerDown = (e) => {
|
const handlePointerDown = (e) => {
|
||||||
!isMobile && e.target.setPointerCapture(e.pointerId);
|
!isMobile && e.target.setPointerCapture(e.pointerId);
|
||||||
onStart && onStart();
|
onStart && onStart();
|
||||||
edgeTimer && clearTimeout(edgeTimer);
|
const { x, y } = position;
|
||||||
const { clientX, clientY } = isMobile ? e.targetTouches[0] : e;
|
const { clientX, clientY } = isMobile ? e.targetTouches[0] : e;
|
||||||
setOrigin({
|
setOrigin({ x, y, clientX, clientY });
|
||||||
x: position.x,
|
|
||||||
y: position.y,
|
|
||||||
px: clientX,
|
|
||||||
py: clientY,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePointerMove = (e) => {
|
const handlePointerMove = (e) => {
|
||||||
onMove && onMove();
|
onMove && onMove();
|
||||||
const { clientX, clientY } = isMobile ? e.targetTouches[0] : e;
|
const { clientX, clientY } = isMobile ? e.targetTouches[0] : e;
|
||||||
if (origin) {
|
if (origin) {
|
||||||
const dx = clientX - origin.px;
|
const dx = clientX - origin.clientX;
|
||||||
const dy = clientY - origin.py;
|
const dy = clientY - origin.clientY;
|
||||||
let x = origin.x + dx;
|
let x = origin.x + dx;
|
||||||
let y = origin.y + dy;
|
let y = origin.y + dy;
|
||||||
const { w, h } = windowSize;
|
x = limitNumber(x, -width / 2, windowWidth - width / 2);
|
||||||
x = limitNumber(x, 0, w - width);
|
y = limitNumber(y, 0, windowHeight - height / 2);
|
||||||
y = limitNumber(y, 0, h - height);
|
setPosition({ x, y });
|
||||||
setPosition({ x, y, edge: null, hide: false });
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePointerUp = (e) => {
|
const handlePointerUp = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setOrigin(null);
|
setOrigin(null);
|
||||||
if (!snapEdge) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
goEdge(windowSize.w, windowSize.h, width, height);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = (e) => {
|
const handleClick = (e) => {
|
||||||
@@ -151,35 +96,48 @@ export default function Draggable({
|
|||||||
|
|
||||||
const handleMouseEnter = (e) => {
|
const handleMouseEnter = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (snapEdge && position.hide) {
|
setHover(true);
|
||||||
edgeTimer && clearTimeout(edgeTimer);
|
};
|
||||||
goEdge(windowSize.w, windowSize.h, width, height);
|
|
||||||
}
|
const handleMouseLeave = (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setHover(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOrigin(null);
|
if (!snapEdge || !!origin) {
|
||||||
if (!snapEdge) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
goEdge(windowSize.w, windowSize.h, width, height);
|
|
||||||
}, [snapEdge, goEdge, windowSize.w, windowSize.h, width, height]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
setPosition((pre) => {
|
||||||
if (position.hide) {
|
const edgePosition = getEdgePosition({
|
||||||
setFab({
|
...pre,
|
||||||
x: position.x,
|
width,
|
||||||
y: position.y,
|
height,
|
||||||
|
windowWidth,
|
||||||
|
windowHeight,
|
||||||
|
hover,
|
||||||
});
|
});
|
||||||
}
|
setFabPosition(edgePosition);
|
||||||
}, [position.x, position.y, position.hide]);
|
return edgePosition;
|
||||||
|
});
|
||||||
|
}, [
|
||||||
|
origin,
|
||||||
|
hover,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
windowWidth,
|
||||||
|
windowHeight,
|
||||||
|
snapEdge,
|
||||||
|
setFabPosition,
|
||||||
|
]);
|
||||||
|
|
||||||
const opacity = useMemo(() => {
|
const opacity = useMemo(() => {
|
||||||
if (snapEdge) {
|
if (snapEdge) {
|
||||||
return position.hide ? 0.2 : 1;
|
return hover || origin ? 1 : 0.2;
|
||||||
}
|
}
|
||||||
return origin ? 0.8 : 1;
|
return origin ? 0.8 : 1;
|
||||||
}, [origin, snapEdge, position.hide]);
|
}, [origin, snapEdge, hover]);
|
||||||
|
|
||||||
const touchProps = isMobile
|
const touchProps = isMobile
|
||||||
? {
|
? {
|
||||||
@@ -205,6 +163,7 @@ export default function Draggable({
|
|||||||
display: show ? "block" : "none",
|
display: show ? "block" : "none",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={handleMouseEnter}
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ export default function Action({ translator, fab }) {
|
|||||||
windowSize,
|
windowSize,
|
||||||
width: fabWidth,
|
width: fabWidth,
|
||||||
height: fabWidth,
|
height: fabWidth,
|
||||||
left: fab.x ?? 0,
|
left: fab.x ?? -fabWidth,
|
||||||
top: fab.y ?? windowSize.h / 2,
|
top: fab.y ?? windowSize.h / 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user