import React, { useState, useEffect } from 'react'; import './MeshTransformGrid.scss'; interface MeshTransformGridProps { imageRef: React.RefObject; // Reference to the image element gridXSize: number; // Number of X subdivisions gridYSize: number; // Number of Y subdivisions isInteractive: boolean; // Whether control points are interactive (can be dragged) } const MeshTransformGrid: React.FC = ({ imageRef, gridXSize, gridYSize, isInteractive }) => { const [controlPoints, setControlPoints] = useState([]); // Set up control points based on image size and grid sizes useEffect(() => { if (imageRef.current) { const { width, height, left, top } = imageRef.current.getBoundingClientRect(); const newControlPoints = []; for (let i = 0; i <= gridYSize; i++) { for (let j = 0; j <= gridXSize; j++) { newControlPoints.push({ id: `${i}-${j}`, x: (j * width) / gridXSize + left, y: (i * height) / gridYSize + top, }); } } setControlPoints(newControlPoints); } }, [imageRef, gridXSize, gridYSize]); // Handle dragging of control points const handleDrag = (e: React.MouseEvent, pointId: string) => { if (!isInteractive) return; // Prevent dragging if grid is not interactive const { clientX, clientY } = e; const updatedPoints = controlPoints.map((point) => { if (point.id === pointId) { return { ...point, x: clientX, y: clientY }; } return point; }); setControlPoints(updatedPoints); }; // Render grid lines between control points const renderGridLines = () => { const lines = []; for (let i = 0; i < controlPoints.length; i++) { const point = controlPoints[i]; const nextPoint = controlPoints[i + 1]; // Horizontal lines if (nextPoint && i % (gridXSize + 1) !== gridXSize) { lines.push({ start: { x: point.x, y: point.y }, end: { x: nextPoint.x, y: nextPoint.y }, }); } // Vertical lines if (i + gridXSize + 1 < controlPoints.length) { const downPoint = controlPoints[i + gridXSize + 1]; lines.push({ start: { x: point.x, y: point.y }, end: { x: downPoint.x, y: downPoint.y }, }); } } return lines.map((line, index) => (
)); }; return (
{renderGridLines()} {controlPoints.map((point) => (
handleDrag(e, point.id)} /> ))}
); }; export default MeshTransformGrid;