Upload components/Canvas.jsx with huggingface_hub
Browse files- components/Canvas.jsx +65 -0
components/Canvas.jsx
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Node from './Node';
|
| 2 |
+
|
| 3 |
+
export default function Canvas({
|
| 4 |
+
nodes,
|
| 5 |
+
connections,
|
| 6 |
+
selectedNodeId,
|
| 7 |
+
selectionSet,
|
| 8 |
+
onNodeSelect,
|
| 9 |
+
onNodeMouseDown,
|
| 10 |
+
onCanvasClick,
|
| 11 |
+
running
|
| 12 |
+
}) {
|
| 13 |
+
return (
|
| 14 |
+
<div
|
| 15 |
+
className="flex-1 bg-deep relative overflow-hidden cursor-grab active:cursor-grabbing bg-[length:40px_40px] bg-grid-pattern"
|
| 16 |
+
onClick={onCanvasClick}
|
| 17 |
+
>
|
| 18 |
+
{/* SVG Connections Layer */}
|
| 19 |
+
<svg className="absolute inset-0 w-full h-full pointer-events-none z-0">
|
| 20 |
+
<defs>
|
| 21 |
+
<linearGradient id="line-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
| 22 |
+
<stop offset="0%" style={{ stopColor: '#3b82f6', stopOpacity: 0.2 }} />
|
| 23 |
+
<stop offset="100%" style={{ stopColor: '#3b82f6', stopOpacity: 1 }} />
|
| 24 |
+
</linearGradient>
|
| 25 |
+
</defs>
|
| 26 |
+
{connections.map((conn, i) => {
|
| 27 |
+
const fromNode = nodes.find(n => n.id === conn.from);
|
| 28 |
+
const toNode = nodes.find(n => n.id === conn.to);
|
| 29 |
+
if (!fromNode || !toNode) return null;
|
| 30 |
+
|
| 31 |
+
// Simple Bezier calculation (assuming node width ~176px, height ~dynamic)
|
| 32 |
+
// Center bottom of source to Center top of target
|
| 33 |
+
const x1 = fromNode.x + 88; // half of w-44
|
| 34 |
+
const y1 = fromNode.y + 80; // approx height
|
| 35 |
+
const x2 = toNode.x + 88;
|
| 36 |
+
const y2 = toNode.y;
|
| 37 |
+
|
| 38 |
+
const d = `M ${x1} ${y1} C ${x1} ${y1 + 60}, ${x2} ${y2 - 60}, ${x2} ${y2}`;
|
| 39 |
+
|
| 40 |
+
return (
|
| 41 |
+
<path
|
| 42 |
+
key={i}
|
| 43 |
+
d={d}
|
| 44 |
+
fill="none"
|
| 45 |
+
stroke="url(#line-gradient)"
|
| 46 |
+
strokeWidth="2"
|
| 47 |
+
className={running ? 'connection-line' : ''}
|
| 48 |
+
/>
|
| 49 |
+
);
|
| 50 |
+
})}
|
| 51 |
+
</svg>
|
| 52 |
+
|
| 53 |
+
{/* Nodes Layer */}
|
| 54 |
+
{nodes.map(node => (
|
| 55 |
+
<Node
|
| 56 |
+
key={node.id}
|
| 57 |
+
node={node}
|
| 58 |
+
isSelected={selectedNodeId === node.id}
|
| 59 |
+
onSelect={onNodeSelect}
|
| 60 |
+
onMouseDown={onNodeMouseDown}
|
| 61 |
+
/>
|
| 62 |
+
))}
|
| 63 |
+
</div>
|
| 64 |
+
);
|
| 65 |
+
}
|