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,
})