Get rid of jointjs

This commit is contained in:
1ilit
2023-09-19 15:47:06 +03:00
parent 62ad20fb1d
commit 1fb3239db0
8 changed files with 371 additions and 76 deletions

View File

@@ -1,47 +1,89 @@
import React, { useEffect, useRef } from "react";
import { dia, shapes } from "jointjs";
import React, { useRef, useState } from "react";
import { useDrop } from "react-dnd";
import Rect from "./rect";
export default function Canvas(props) {
const [dragging, setDragging] = useState(false);
const [offset, setOffset] = useState({ x: 0, y: 0 });
export default function DrawArea(props) {
const canvas = useRef(null);
const [, drop] = useDrop(() => ({
accept: "CARD",
drop: (item, monitor) => {
const offset = monitor.getClientOffset();
const canvasRect = canvas.current.getBoundingClientRect();
const x = offset.x - canvasRect.left - item.size.width * 0.5;
const y = offset.y - canvasRect.top - item.size.height * 0.5;
if (item.type === "rect") {
const rect = new shapes.standard.Rectangle();
rect.position(x, y);
rect.resize(item.size.width, item.size.height);
rect.attr(item.attrs);
rect.addTo(props.graph);
props.setCode((prevCode) => `create table hi\n\n${prevCode}`);
}
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
}));
useEffect(() => {
new dia.Paper({
el: document.getElementById("canvas"),
background: {
color: "#aec3b0",
},
model: props.graph,
width: "100%",
gridSize: 1,
interactive: true,
const handleMouseDown = (event, id) => {
const { clientX, clientY } = event;
const rectangle = props.rectangles.find((rect) => rect.id === id);
setOffset({
x: clientX - rectangle.x,
y: clientY - rectangle.y,
});
}, [props.graph]);
setDragging(id);
};
const handleMouseMove = (event) => {
if (dragging === false) return;
const { clientX, clientY } = event;
const updatedRectangles = props.rectangles.map((rect) => {
if (rect.id === dragging) {
return {
...rect,
x: clientX - offset.x,
y: clientY - offset.y,
};
}
return rect;
});
props.setRectangles(updatedRectangles);
};
const handleMouseUp = () => {
setDragging(false);
};
const [, drop] = useDrop(
() => ({
accept: "CARD",
drop: (item, monitor) => {
const offset = monitor.getClientOffset();
const canvasRect = canvas.current.getBoundingClientRect();
const x = offset.x - canvasRect.left - 100 * 0.5;
const y = offset.y - canvasRect.top - 100 * 0.5;
const newRectangle = {
id: props.rectangles.length + 1,
x,
y,
width: 100,
height: 100,
label: `rect ${props.rectangles.length + 1}`,
};
props.setRectangles([...props.rectangles, newRectangle]);
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
}),
[props.rectangles]
);
return (
<div ref={drop} className="flex-grow">
<div id="canvas" ref={canvas}></div>
<div ref={drop} className="flex-grow" id="canvas">
<div ref={canvas} className="w-full h-screen">
<svg
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
style={{ width: "100%", height: "100%" }}
>
{props.rectangles.map((rectangle) => (
<Rect
key={rectangle.id}
x={rectangle.x}
y={rectangle.y}
label={rectangle.label}
width={rectangle.width}
height={rectangle.height}
onMouseDown={(event) => handleMouseDown(event, rectangle.id)}
/>
))}
</svg>
</div>
</div>
);
}

View File

@@ -49,20 +49,15 @@ export default function EditorPanel(props) {
<br />
<button
onClick={() => {
const rect = new shapes.standard.Rectangle();
rect.position(100, 100);
rect.resize(100, 40);
rect.attr({
body: {
fill: "#7039FF",
},
label: {
text: "hi",
fill: "white",
},
});
rect.addTo(props.graph);
props.setCode((prevCode) => `create table hi\n\n${prevCode}`);
const newRectangle = {
id: props.rectangles.length + 1,
x: 0,
y: 0,
width: 100,
height: 100,
label: `rect ${props.rectangles.length + 1}`,
};
props.setRectangles([...props.rectangles, newRectangle]);
}}
>
add

27
src/components/rect.jsx Normal file
View File

@@ -0,0 +1,27 @@
import React from "react";
const Rect = (props) => {
return (
<g>
<rect
key={props.id}
x={props.x}
y={props.y}
width={props.width}
height={props.height}
style={{ fill: "blue", cursor: "move" }}
onMouseDown={props.onMouseDown}
/>
<text
x={props.x + 50}
y={props.y + 50}
textAnchor="middle"
style={{ fill: "white" }}
>
{props.label}
</text>
</g>
);
};
export default Rect;

View File

@@ -1,25 +1,9 @@
import {React} from "react"
import { React } from "react";
import { useDrag } from "react-dnd";
export default function Shape (){
const rectData = {
type: "rect",
position: { x: 100, y: 100 },
size: { width: 100, height: 40 },
attrs: {
body: {
fill: "#7039FF",
},
label: {
text: "hi",
fill: "white",
},
},
};
export default function Shape() {
const [{ isDragging }, drag] = useDrag(() => ({
type: "CARD",
item: rectData,
collect: (monitor) => ({
isDragging: !!monitor.isDragging(),
}),
@@ -38,4 +22,4 @@ export default function Shape (){
rect
</div>
);
};
}

View File

@@ -1,16 +1,25 @@
import { React, useState, useMemo } from "react";
import React, { useState } from "react";
import Header from "../components/header";
import Sidebar from "../components/sidebar";
import ControlPanel from "../components/control_panel";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { dia } from "jointjs";
import DrawArea from "../components/draw_area";
import Canvas from "../components/draw_area";
import EditorPanel from "../components/editor_panel";
// class Graph {
// constructor() {
// this.nodes = [];
// }
// setNodes(nodes) {
// this.nodes = nodes;
// }
// }
export default function Editor(props) {
const graph = useMemo(() => new dia.Graph(), []);
const [code, setCode] = useState("");
const [rectangles, setRectangles] = useState([]);
return (
<>
@@ -18,8 +27,18 @@ export default function Editor(props) {
<ControlPanel />
<div className="flex h-full">
<DndProvider backend={HTML5Backend}>
<EditorPanel graph={graph} code={code} setCode={setCode}/>
<DrawArea graph={graph} code={code} setCode={setCode}/>
<EditorPanel
rectangles={rectangles}
setRectangles={setRectangles}
code={code}
setCode={setCode}
/>
<Canvas
rectangles={rectangles}
setRectangles={setRectangles}
code={code}
setCode={setCode}
/>
</DndProvider>
<Sidebar />
</div>

View File

@@ -5,6 +5,7 @@ export default function LandingPage() {
return (
<div>
<Link to="/editor">editor</Link>
<br />
LandingPage
</div>
);