import state, { useSelector } from "state" import styled from "styles" import inputs from "state/inputs" import { useRef } from "react" import { TransformCorner, TransformEdge } from "types" import { lerp } from "utils/utils" export default function Bounds() { const isBrushing = useSelector((s) => s.isIn("brushSelecting")) const isSelecting = useSelector((s) => s.isIn("selecting")) const zoom = useSelector((s) => s.data.camera.zoom) const bounds = useSelector((s) => s.values.selectedBounds) const rotation = useSelector((s) => { if (s.data.selectedIds.size === 1) { const { shapes } = s.data.document.pages[s.data.currentPageId] const selected = Array.from(s.data.selectedIds.values())[0] return shapes[selected].rotation } else { return 0 } }) if (!bounds) return null if (!isSelecting) return null let { minX, minY, maxX, maxY, width, height } = bounds const p = 4 / zoom const cp = p * 2 return ( ) } function RotateHandle({ x, y, r }: { x: number; y: number; r: number }) { const rRotateHandle = useRef(null) return ( { e.stopPropagation() rRotateHandle.current.setPointerCapture(e.pointerId) state.send("POINTED_ROTATE_HANDLE", inputs.pointerDown(e, "rotate")) }} onPointerUp={(e) => { e.stopPropagation() rRotateHandle.current.releasePointerCapture(e.pointerId) rRotateHandle.current.replaceWith(rRotateHandle.current) state.send("STOPPED_POINTING", inputs.pointerDown(e, "rotate")) }} /> ) } function Corner({ x, y, width, height, corner, }: { x: number y: number width: number height: number corner: TransformCorner }) { const rCorner = useRef(null) return ( { e.stopPropagation() rCorner.current.setPointerCapture(e.pointerId) state.send("POINTED_BOUNDS_CORNER", inputs.pointerDown(e, corner)) }} onPointerUp={(e) => { e.stopPropagation() rCorner.current.releasePointerCapture(e.pointerId) rCorner.current.replaceWith(rCorner.current) state.send("STOPPED_POINTING", inputs.pointerDown(e, corner)) }} /> ) } function EdgeHorizontal({ x, y, width, height, edge, }: { x: number y: number width: number height: number edge: TransformEdge.Top | TransformEdge.Bottom }) { const rEdge = useRef(null) return ( { e.stopPropagation() rEdge.current.setPointerCapture(e.pointerId) state.send("POINTED_BOUNDS_EDGE", inputs.pointerDown(e, edge)) }} onPointerUp={(e) => { e.stopPropagation() e.preventDefault() state.send("STOPPED_POINTING", inputs.pointerUp(e)) rEdge.current.releasePointerCapture(e.pointerId) rEdge.current.replaceWith(rEdge.current) }} edge={edge} /> ) } function EdgeVertical({ x, y, width, height, edge, }: { x: number y: number width: number height: number edge: TransformEdge.Right | TransformEdge.Left }) { const rEdge = useRef(null) return ( { e.stopPropagation() state.send("POINTED_BOUNDS_EDGE", inputs.pointerDown(e, edge)) rEdge.current.setPointerCapture(e.pointerId) }} onPointerUp={(e) => { e.stopPropagation() state.send("STOPPED_POINTING", inputs.pointerUp(e)) rEdge.current.releasePointerCapture(e.pointerId) rEdge.current.replaceWith(rEdge.current) }} edge={edge} /> ) } const StyledEdge = styled("rect", { stroke: "none", fill: "none", variants: { edge: { bottom_edge: { cursor: "ns-resize" }, right_edge: { cursor: "ew-resize" }, top_edge: { cursor: "ns-resize" }, left_edge: { cursor: "ew-resize" }, }, }, }) const StyledCorner = styled("rect", { stroke: "$bounds", fill: "#fff", zStrokeWidth: 2, variants: { corner: { top_left_corner: { cursor: "nwse-resize" }, top_right_corner: { cursor: "nesw-resize" }, bottom_right_corner: { cursor: "nwse-resize" }, bottom_left_corner: { cursor: "nesw-resize" }, }, }, }) const StyledRotateHandle = styled("circle", { stroke: "$bounds", fill: "#fff", zStrokeWidth: 2, cursor: "grab", }) const StyledBounds = styled("rect", { fill: "none", stroke: "$bounds", zStrokeWidth: 2, })