From 7a8493310794454ac9b4e55f98866555ee9cc355 Mon Sep 17 00:00:00 2001 From: Gabe Yuan Date: Wed, 9 Aug 2023 22:45:43 +0800 Subject: [PATCH] optimize fab --- src/views/Action/Draggable.js | 109 ++++++++++++++++++++++++---------- src/views/Action/index.js | 4 +- 2 files changed, 78 insertions(+), 35 deletions(-) diff --git a/src/views/Action/Draggable.js b/src/views/Action/Draggable.js index 0db0239..696e7e7 100644 --- a/src/views/Action/Draggable.js +++ b/src/views/Action/Draggable.js @@ -1,17 +1,59 @@ -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { limitNumber } from "../../libs/utils"; import { isMobile } from "../../libs/mobile"; -export default function Draggable(props) { - const [origin, setOrigin] = useState(null); +const getSidePosition = ( + windowWidth, + windowHeight, + width, + height, + left, + top +) => { + const right = Math.abs(windowWidth - left - width); + const bottom = Math.abs(windowHeight - top - height); + left = Math.abs(left); + top = Math.abs(top); + const min = Math.min(left, top, right, bottom); + switch (min) { + 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 }; +}; + +export default function Draggable({ + windowSize, + width, + height, + left, + top, + show, + goside, + onStart, + onMove, + handler, + children, +}) { + const [origin, setOrigin] = useState(goside ? {} : null); const [position, setPosition] = useState({ - x: props.left, - y: props.top, + x: left, + y: top, }); const handlePointerDown = (e) => { !isMobile && e.target.setPointerCapture(e.pointerId); - props?.onStart(); + onStart && onStart(); const { clientX, clientY } = isMobile ? e.targetTouches[0] : e; setOrigin({ x: position.x, @@ -22,37 +64,28 @@ export default function Draggable(props) { }; const handlePointerMove = (e) => { - props?.onMove(); + onMove && onMove(); const { clientX, clientY } = isMobile ? e.targetTouches[0] : e; if (origin) { const dx = clientX - origin.px; const dy = clientY - origin.py; let x = origin.x + dx; let y = origin.y + dy; - const { w, h } = props.windowSize; - x = limitNumber(x, -props.width / 2, w - props.width / 2); - y = limitNumber(y, -props.height / 2, h - props.height / 2); + const { w, h } = windowSize; + x = limitNumber(x, -width / 2, w - width / 2); + y = limitNumber(y, -height / 2, h - height / 2); setPosition({ x, y }); } }; const handlePointerUp = (e) => { setOrigin(null); - - if (!props.goside) { + if (!goside) { return; } - - const { w, h } = props.windowSize; - let { x: left, y: top } = position; - const right = w - left - props.width; - const bottom = h - top - props.height; - const min = Math.min(left, top, right, bottom); - left === min && (left = -props.width / 2); - top === min && (top = -props.height / 2); - right === min && (left = w - props.width / 2); - bottom === min && (top = h - props.height / 2); - setPosition({ x: left, y: top }); + setPosition((pre) => + getSidePosition(windowSize.w, windowSize.h, width, height, pre.x, pre.y) + ); }; const handleClick = (e) => { @@ -72,23 +105,33 @@ export default function Draggable(props) { }; useEffect(() => { - const { w, h } = props.windowSize; - setPosition(({ x, y }) => ({ - x: limitNumber(x, -props.width / 2, w - props.width / 2), - y: limitNumber(y, -props.height / 2, h - props.height / 2), - })); - }, [props.windowSize, props.width, props.height]); + setOrigin(null); + if (!goside) { + return; + } + setPosition((pre) => + getSidePosition(windowSize.w, windowSize.h, width, height, pre.x, pre.y) + ); + }, [goside, windowSize.w, windowSize.h, width, height]); + + const opacity = useMemo(() => { + if (goside) { + return origin ? 1 : 0.3; + } + return origin ? 0.7 : 1; + }, [origin, goside]); return (
- {props.handler} + {handler}
-
{props.children}
+
{children}
); } diff --git a/src/views/Action/index.js b/src/views/Action/index.js index ed27a4f..a87e88f 100644 --- a/src/views/Action/index.js +++ b/src/views/Action/index.js @@ -67,8 +67,8 @@ export default function Action({ translator }) { windowSize, width: fabWidth, height: fabWidth, - left: window.innerWidth - fabWidth - fabWidth / 2, - top: window.innerHeight - fabWidth - fabWidth, + left: window.innerWidth - fabWidth, + top: window.innerHeight / 2, }; return (