tranbox...
This commit is contained in:
248
src/views/Selection/DraggableResizable.js
Normal file
248
src/views/Selection/DraggableResizable.js
Normal file
@@ -0,0 +1,248 @@
|
||||
import { useState } from "react";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
function Pointer({
|
||||
direction,
|
||||
size,
|
||||
setSize,
|
||||
position,
|
||||
setPosition,
|
||||
children,
|
||||
minSize,
|
||||
maxSize,
|
||||
...props
|
||||
}) {
|
||||
const [origin, setOrigin] = useState(null);
|
||||
|
||||
function handlePointerDown(e) {
|
||||
e.target.setPointerCapture(e.pointerId);
|
||||
setOrigin({
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
w: size.w,
|
||||
h: size.h,
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY,
|
||||
});
|
||||
}
|
||||
|
||||
function handlePointerMove(e) {
|
||||
if (origin) {
|
||||
const dx = e.clientX - origin.clientX;
|
||||
const dy = e.clientY - origin.clientY;
|
||||
let x = position.x;
|
||||
let y = position.y;
|
||||
let w = size.w;
|
||||
let h = size.h;
|
||||
|
||||
switch (direction) {
|
||||
case "Header":
|
||||
x = origin.x + dx;
|
||||
y = origin.y + dy;
|
||||
break;
|
||||
case "TopLeft":
|
||||
x = origin.x + dx;
|
||||
y = origin.y + dy;
|
||||
w = origin.w - dx;
|
||||
h = origin.h - dy;
|
||||
break;
|
||||
case "Top":
|
||||
y = origin.y + dy;
|
||||
h = origin.h - dy;
|
||||
break;
|
||||
case "TopRight":
|
||||
y = origin.y + dy;
|
||||
w = origin.w + dx;
|
||||
h = origin.h - dy;
|
||||
break;
|
||||
case "Left":
|
||||
x = origin.x + dx;
|
||||
w = origin.w - dx;
|
||||
break;
|
||||
case "Right":
|
||||
w = origin.w + dx;
|
||||
break;
|
||||
case "BottomLeft":
|
||||
x = origin.x + dx;
|
||||
w = origin.w - dx;
|
||||
h = origin.h + dy;
|
||||
break;
|
||||
case "Bottom":
|
||||
h = origin.h + dy;
|
||||
break;
|
||||
case "BottomRight":
|
||||
w = origin.w + dx;
|
||||
h = origin.h + dy;
|
||||
break;
|
||||
}
|
||||
|
||||
if (w < minSize.w) {
|
||||
w = minSize.w;
|
||||
x = position.x;
|
||||
}
|
||||
if (w > maxSize.w) {
|
||||
w = maxSize.w;
|
||||
x = position.x;
|
||||
}
|
||||
if (h < minSize.h) {
|
||||
h = minSize.h;
|
||||
y = position.y;
|
||||
}
|
||||
if (h > maxSize.h) {
|
||||
h = maxSize.h;
|
||||
y = position.y;
|
||||
}
|
||||
|
||||
setPosition({ x, y });
|
||||
setSize({ w, h });
|
||||
}
|
||||
}
|
||||
|
||||
function handlePointerUp(e) {
|
||||
setOrigin(null);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
onPointerDown={handlePointerDown}
|
||||
onPointerMove={handlePointerMove}
|
||||
onPointerUp={handlePointerUp}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function DraggableResizable({
|
||||
header,
|
||||
children,
|
||||
defaultPosition = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
defaultSize = {
|
||||
w: 600,
|
||||
h: 400,
|
||||
},
|
||||
minSize = {
|
||||
w: 300,
|
||||
h: 200,
|
||||
},
|
||||
maxSize = {
|
||||
w: 1200,
|
||||
h: 1200,
|
||||
},
|
||||
sx,
|
||||
}) {
|
||||
const lineWidth = 4;
|
||||
const [position, setPosition] = useState(defaultPosition);
|
||||
const [size, setSize] = useState(defaultSize);
|
||||
|
||||
const opts = {
|
||||
size,
|
||||
setSize,
|
||||
position,
|
||||
setPosition,
|
||||
minSize,
|
||||
maxSize,
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
position: "fixed",
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
display: "grid",
|
||||
gridTemplateColumns: `${lineWidth * 2}px auto ${lineWidth * 2}px`,
|
||||
gridTemplateRows: `${lineWidth * 2}px auto ${lineWidth * 2}px`,
|
||||
zIndex: 10000,
|
||||
}}
|
||||
>
|
||||
<Pointer
|
||||
direction="TopLeft"
|
||||
style={{
|
||||
transform: `translate(${lineWidth}px, ${lineWidth}px)`,
|
||||
cursor: "nw-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Pointer
|
||||
direction="Top"
|
||||
style={{
|
||||
margin: `0 ${lineWidth}px`,
|
||||
transform: `translate(0px, ${lineWidth}px)`,
|
||||
cursor: "row-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Pointer
|
||||
direction="TopRight"
|
||||
style={{
|
||||
transform: `translate(-${lineWidth}px, ${lineWidth}px)`,
|
||||
cursor: "ne-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Pointer
|
||||
direction="Left"
|
||||
style={{
|
||||
margin: `${lineWidth}px 0`,
|
||||
transform: `translate(${lineWidth}px, 0px)`,
|
||||
cursor: "col-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Paper elevation={4}>
|
||||
<Pointer direction="Header" style={{ cursor: "move" }} {...opts}>
|
||||
{header}
|
||||
</Pointer>
|
||||
<div
|
||||
style={{
|
||||
width: size.w,
|
||||
height: size.h,
|
||||
overflow: "hidden auto",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</Paper>
|
||||
<Pointer
|
||||
direction="Right"
|
||||
style={{
|
||||
margin: `${lineWidth}px 0`,
|
||||
transform: `translate(-${lineWidth}px, 0px)`,
|
||||
cursor: "col-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Pointer
|
||||
direction="BottomLeft"
|
||||
style={{
|
||||
transform: `translate(${lineWidth}px, -${lineWidth}px)`,
|
||||
cursor: "ne-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Pointer
|
||||
direction="Bottom"
|
||||
style={{
|
||||
margin: `0 ${lineWidth}px`,
|
||||
transform: `translate(0px, -${lineWidth}px)`,
|
||||
cursor: "row-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
<Pointer
|
||||
direction="BottomRight"
|
||||
style={{
|
||||
transform: `translate(-${lineWidth}px, -${lineWidth}px)`,
|
||||
cursor: "nw-resize",
|
||||
}}
|
||||
{...opts}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user