aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/imageEditor/imageMeshTool/imageMesh.tsx
blob: ee5c597e9d454ae7ec95f5c0ed0c91a244e5b085 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import React, { useState, useEffect } from 'react';
import './MeshTransformGrid.scss';

interface MeshTransformGridProps {
    imageRef: React.RefObject<HTMLImageElement>;  // 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<MeshTransformGridProps> = ({ imageRef, gridXSize, gridYSize, isInteractive }) => {
    const [controlPoints, setControlPoints] = useState<any[]>([]);

    // 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) => (
            <div
                key={index}
                className="grid-line"
                style={{
                    position: 'absolute',
                    left: `${line.start.x}px`,
                    top: `${line.start.y}px`,
                    width: `${Math.abs(line.end.x - line.start.x)}px`,
                    height: `${Math.abs(line.end.y - line.start.y)}px`,
                    border: '1px solid rgba(255, 255, 255, 0.6)',
                }}
            />
        ));
    };

    return (
        <div className="meshTransformGrid">
            {renderGridLines()}

            {controlPoints.map((point) => (
                <div
                    key={point.id}
                    className="control-point"
                    style={{
                        left: `${point.x}px`,
                        top: `${point.y}px`,
                        transform: 'translate(-50%, -50%)',
                    }}
                    draggable={isInteractive} // Only allow dragging if interactive
                    onDrag={(e) => handleDrag(e, point.id)}
                />
            ))}
        </div>
    );
};

export default MeshTransformGrid;