File size: 2,663 Bytes
19abe39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1e49495
 
 
 
 
19abe39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1e49495
 
 
 
 
 
 
 
 
 
 
 
 
 
19abe39
 
1e49495
19abe39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1e49495
19abe39
 
 
 
 
 
 
 
 
 
 
 
 
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
const MOUNTAIN = '#f59e0b';
const VALLEY = '#38bdf8';

function toSvg(x, y, dim) {
  return [x * dim, (1 - y) * dim];
}

function GhostEdges({ target, dim }) {
  if (!target) return null;
  const { vertices_coords, edges_vertices, edges_assignment } = target;
  if (!vertices_coords || !edges_vertices || !edges_assignment) return null;

  return edges_vertices.map((ev, i) => {
    const asgn = edges_assignment[i];
    if (asgn === 'B') return null;
    const v1 = vertices_coords[ev[0]];
    const v2 = vertices_coords[ev[1]];
    if (!v1 || !v2) return null;
    const [x1, y1] = toSvg(v1[0], v1[1], dim);
    const [x2, y2] = toSvg(v2[0], v2[1], dim);
    const color = asgn === 'M' ? MOUNTAIN : VALLEY;
    return (
      <line
        key={i}
        x1={x1} y1={y1} x2={x2} y2={y2}
        stroke={color}
        strokeOpacity={0.25}
        strokeWidth={1.5}
        strokeDasharray="5 4"
      />
    );
  });
}

function CurrentEdges({ paperState, dim }) {
  if (!paperState) return null;
  const { vertices_coords, edges_vertices, edges_assignment } = paperState;
  if (!vertices_coords || !edges_vertices || !edges_assignment) return null;

  return edges_vertices.map((ev, i) => {
    const asgn = edges_assignment[i];
    if (asgn === 'B' || asgn === 'F') return null;
    const v1 = vertices_coords[ev[0]];
    const v2 = vertices_coords[ev[1]];
    if (!v1 || !v2) return null;
    // vertices_coords are 3D [x, y, z] — use only x and y
    const [x1, y1] = toSvg(v1[0], v1[1], dim);
    const [x2, y2] = toSvg(v2[0], v2[1], dim);
    const color = asgn === 'M' ? MOUNTAIN : VALLEY;
    return (
      <line
        key={i}
        x1={x1} y1={y1} x2={x2} y2={y2}
        stroke={color}
        strokeWidth={2.5}
        strokeLinecap="square"
      />
    );
  });
}

export default function CreaseCanvas({ paperState, target, dim = 280, ghostOnly = false }) {
  const pad = 1;
  const size = dim;

  return (
    <svg
      className="canvas-svg"
      width={size}
      height={size}
      viewBox={`0 0 ${size} ${size}`}
      style={{ flexShrink: 0 }}
    >
      {/* Paper background */}
      <rect
        x={pad} y={pad}
        width={size - pad * 2} height={size - pad * 2}
        fill="#fafaf5"
      />

      {/* Ghost target overlay */}
      <GhostEdges target={target} dim={size} />

      {/* Current paper state */}
      {!ghostOnly && (
        <CurrentEdges paperState={paperState} dim={size} />
      )}

      {/* Paper border */}
      <rect
        x={pad} y={pad}
        width={size - pad * 2} height={size - pad * 2}
        fill="none"
        stroke="#2a2a3a"
        strokeWidth={1}
      />
    </svg>
  );
}