Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
2.6 kB
2
Indexable
import React, { useRef, useState } from 'react';
import { useDrag, useDrop, DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

const SidebarItem = ({ type }) => {
  const [{ isDragging }, drag] = useDrag({
    item: { type },
    collect: (monitor) => ({
      isDragging: monitor.isDragging()
    })
  });

  return (
    <div
      ref={drag}
      style={{ opacity: isDragging ? 0.5 : 1 }}
      className="sidebar-item"
    >
      {type}
    </div>
  );
};

const CanvasElement = ({ type, x, y }) => {
  const [{ isDragging }, drag] = useDrag({
    item: { type, x, y },
    collect: (monitor) => ({
      isDragging: monitor.isDragging()
    })
  });

  return (
    <div
      ref={drag}
      style={{
        position: 'absolute',
        left: x,
        top: y,
        opacity: isDragging ? 0.5 : 1
      }}
      className="canvas-element"
    >
      {type}
    </div>
  );
};

const Canvas = () => {
  const canvasRef = useRef(null);
  const [elements, setElements] = useState([]);
  const [isOver, setIsOver] = useState(false);

  const handleDrop = (type, x, y) => {
    setElements((prevElements) => [
      ...prevElements,
      { type, x, y }
    ]);
  };

  const [{ canDrop }, drop] = useDrop({
    accept: 'sidebar-item',
    drop: (item, monitor) => {
      const { left, top } = canvasRef.current.getBoundingClientRect();
      const x = monitor.getClientOffset().x - left;
      const y = monitor.getClientOffset().y - top;
      handleDrop(item.type, x, y);
    },
    collect: (monitor) => ({
      canDrop: monitor.canDrop()
    })
  });

  return (
    <div
      ref={drop}
      onDragEnter={() => setIsOver(true)}
      onDragLeave={() => setIsOver(false)}
      className={`canvas ${isOver ? 'canvas-over' : ''}`}
    >
      <div ref={canvasRef} className="canvas-inner">
        {elements.map((element, index) => (
          <CanvasElement key={index} type={element.type} x={element.x} y={element.y} />
        ))}
      </div>
    </div>
  );
};

const Sidebar = () => {
  return (
    <div className="sidebar">
      <h2>Sidebar</h2>
      <SidebarItem type="Resistor" />
      <SidebarItem type="Capacitor" />
      {/* Add more electrical elements as needed */}
    </div>
  );
};

const App = () => {
  return (
    <div className="app">
      <DndProvider backend={HTML5Backend}>
        <Sidebar />
        <Canvas />
      </DndProvider>
    </div>
  );
};

export default App;