From 5ec39e288f9f72a38df31c474c75c08f83641d4c Mon Sep 17 00:00:00 2001 From: Robby6Strings Date: Tue, 9 Apr 2024 10:32:48 +1200 Subject: [PATCH] devtools host - btn anchor tweening WIP --- packages/devtools-host/src/App.tsx | 154 +++++++++++++++++++++++++---- 1 file changed, 135 insertions(+), 19 deletions(-) diff --git a/packages/devtools-host/src/App.tsx b/packages/devtools-host/src/App.tsx index 35e6b081..5e1463e5 100644 --- a/packages/devtools-host/src/App.tsx +++ b/packages/devtools-host/src/App.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "kaioken" +import { signal, useEffect, useMemo, useState } from "kaioken" import { __useDevtoolsStore } from "./store" //@ts-ignore import { useTween, useWindowSize } from "@kaioken-core/hooks" @@ -6,11 +6,89 @@ import { useTween, useWindowSize } from "@kaioken-core/hooks" const size = 30 const padding = 15 +type Vec2 = { x: number; y: number } + +const mouseDrag = signal<{ + origin: Vec2 + delta: Vec2 + dragging: boolean + mouseDown: boolean +}>({ + origin: { x: 0, y: 0 }, + delta: { x: 0, y: 0 }, + dragging: false, + mouseDown: false, +}) + +type Corner = "tl" | "tr" | "bl" | "br" + +const corner = signal("br") + +function handlePointerMove(e: PointerEvent) { + if (!mouseDrag.value.mouseDown) return + mouseDrag.value.delta.x += e.movementX + mouseDrag.value.delta.y += e.movementY + if ( + Math.abs(mouseDrag.value.delta.x) > 5 || + Math.abs(mouseDrag.value.delta.y) > 5 + ) { + mouseDrag.value.dragging = true + mouseDrag.notify() + } +} + +function handlePointerUp(e: PointerEvent) { + if (!mouseDrag.value.dragging) return + e.preventDefault() + e.stopImmediatePropagation() + e.stopPropagation() + window.removeEventListener("pointermove", handlePointerMove) + window.removeEventListener("pointerup", handlePointerUp) + const newCorner = getCorner() + console.log("newCorner", newCorner) + if (corner.value !== newCorner) corner.value = newCorner + mouseDrag.value.mouseDown = false + mouseDrag.notify() +} + +function getCorner() { + let isTop = true + let isLeft = true + const { width, height } = getBounds() + if (mouseDrag.value.origin.x + mouseDrag.value.delta.x > width / 2) { + isLeft = false + } + if (mouseDrag.value.origin.y + mouseDrag.value.delta.y > height / 2) { + isTop = false + } + + if (isTop) { + if (isLeft) { + return "tl" + } else { + return "tr" + } + } else { + if (isLeft) { + return "bl" + } else { + return "br" + } + } +} + +function getBounds() { + return { + width: Math.min(window.innerWidth, document.body.clientWidth), + height: Math.min(window.innerHeight, document.body.clientHeight), + } +} + export default function __DevtoolsApp() { - const [corner, setCorner] = useState<"br" | "bl" | "tl" | "tr">("br") const { width, height } = useWindowSize() const _width = Math.min(width, document.body.clientWidth) // handle scrollbars + const _height = Math.min(height, document.body.clientHeight) // handle scrollbars const topLeftOffset = () => ({ x: padding, @@ -19,16 +97,35 @@ export default function __DevtoolsApp() { const topRightOffset = () => ({ x: _width - size - padding, y: padding }) const bottomRightOffset = () => ({ x: _width - size - padding, - y: height - size - padding, + y: _height - size - padding, }) - const bottomLeftOffset = () => ({ x: padding, y: height - size - padding }) + const bottomLeftOffset = () => ({ x: padding, y: _height - size - padding }) - const coords = useMemo(() => { - if (corner === "br") return bottomRightOffset() - if (corner === "bl") return bottomLeftOffset() - if (corner === "tl") return topLeftOffset() - else return topRightOffset() - }, [corner, width, height]) + const [coords, setCoords] = useTween(bottomRightOffset) + + useEffect(() => { + let newOffset: Vec2 = { x: 0, y: 0 } + switch (corner.value) { + case "tl": + newOffset = topLeftOffset() + break + case "tr": + newOffset = topRightOffset() + break + case "bl": + newOffset = bottomLeftOffset() + break + case "br": + newOffset = bottomRightOffset() + } + console.log("useEffect offset", newOffset, coords) + setCoords(newOffset, { + duration: + coords.x === -size - padding && coords.y === -size - padding ? 0 : 300, + }).then(() => { + mouseDrag.value.dragging = false + }) + }, [corner.value, _width, _height]) const { value: { popupWindow }, @@ -36,33 +133,52 @@ export default function __DevtoolsApp() { } = __useDevtoolsStore() function handleOpen() { + if (mouseDrag.value.dragging) return + mouseDrag.value.mouseDown = false if (popupWindow) return popupWindow.focus() const w = window.open("/__devtools__", "_blank", "popup") if (!w) return console.error("[kaioken]: Unable to open devtools window") w.onload = () => { setPopupWindow(w) - console.log("devtools window opened") + console.log("[kaioken]: devtools window opened") w.onbeforeunload = () => { - console.log("devtools window closed") + console.log("[kaioken]: devtools window closed") setPopupWindow(null) } } } + return ( <> - - - -
-