"use client"; import { useRef } from "react"; import { useDrop } from "react-dnd"; import { useBarcodeDesigner, MM_TO_PX } from "@/contexts/BarcodeDesignerContext"; import { BarcodeLabelCanvasComponent } from "./BarcodeLabelCanvasComponent"; import { BarcodeLabelComponent } from "@/types/barcode"; import { v4 as uuidv4 } from "uuid"; export function BarcodeDesignerCanvas() { const canvasRef = useRef(null); const { widthMm, heightMm, components, addComponent, selectComponent, showGrid, snapValueToGrid, } = useBarcodeDesigner(); const widthPx = widthMm * MM_TO_PX; const heightPx = heightMm * MM_TO_PX; const [{ isOver }, drop] = useDrop(() => ({ accept: "barcode-component", drop: (item: { component: BarcodeLabelComponent }, monitor) => { if (!canvasRef.current) return; const offset = monitor.getClientOffset(); const rect = canvasRef.current.getBoundingClientRect(); if (!offset) return; let x = offset.x - rect.left; let y = offset.y - rect.top; // 드롭 시 요소 중앙이 커서에 오도록 보정 x -= item.component.width / 2; y -= item.component.height / 2; x = Math.max(0, Math.min(x, widthPx - item.component.width)); y = Math.max(0, Math.min(y, heightPx - item.component.height)); const newComp: BarcodeLabelComponent = { ...item.component, id: `comp_${uuidv4()}`, x: snapValueToGrid(x), y: snapValueToGrid(y), zIndex: components.length, }; addComponent(newComp); }, collect: (m) => ({ isOver: m.isOver() }), }), [widthPx, heightPx, components.length, addComponent, snapValueToGrid]); return (
{ (canvasRef as any).current = r; drop(r); }} className="relative bg-white shadow-lg" style={{ width: widthPx, height: heightPx, minWidth: widthPx, minHeight: heightPx, backgroundImage: showGrid ? `linear-gradient(to right, #e5e7eb 1px, transparent 1px), linear-gradient(to bottom, #e5e7eb 1px, transparent 1px)` : undefined, backgroundSize: showGrid ? `${MM_TO_PX * 5}px ${MM_TO_PX * 5}px` : undefined, outline: isOver ? "2px dashed #2563eb" : "1px solid #d1d5db", }} onClick={(e) => { if (e.target === e.currentTarget) selectComponent(null); }} > {components.map((c) => ( ))}
); }