@operato/scene-wheel-sorter 10.0.0-beta.12 → 10.0.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -59,7 +59,8 @@ export class Conveyor3D extends RealObjectGroup {
59
59
  const rollerDiameter = Math.max(rollWidth, 2);
60
60
  const frameH = rollerDiameter;
61
61
  const legH = Math.max(depth - frameH, 0);
62
- const railW = Math.max(height * 0.06, 2);
62
+ const beltWidth = isVertical ? width : height;
63
+ const railW = Math.max(beltWidth * 0.06, 2);
63
64
  const legThickness = Math.max(railW * 0.8, 2);
64
65
  const frameMaterial = new THREE.MeshStandardMaterial({
65
66
  color: FRAME_COLOR,
@@ -69,40 +70,66 @@ export class Conveyor3D extends RealObjectGroup {
69
70
  // --- Frame: side rails + legs + cross-bracing ---
70
71
  const frameGeometries = [];
71
72
  const railY = depth / 2 - frameH / 2;
72
- // Side rails (along X)
73
- for (const zSign of [-1, 1]) {
74
- const rail = new THREE.BoxGeometry(width, frameH, railW);
75
- rail.translate(0, railY, zSign * (height / 2 - railW / 2));
76
- frameGeometries.push(rail);
73
+ // Side rails 이송 방향을 따라, 벨트 양측에 배치
74
+ if (isVertical) {
75
+ for (const xSign of [-1, 1]) {
76
+ const rail = new THREE.BoxGeometry(railW, frameH, height);
77
+ rail.translate(xSign * (width / 2 - railW / 2), railY, 0);
78
+ frameGeometries.push(rail);
79
+ }
77
80
  }
78
- // 4 legs at corners — 레일 바로 아래에 정렬
81
+ else {
82
+ for (const zSign of [-1, 1]) {
83
+ const rail = new THREE.BoxGeometry(width, frameH, railW);
84
+ rail.translate(0, railY, zSign * (height / 2 - railW / 2));
85
+ frameGeometries.push(rail);
86
+ }
87
+ }
88
+ // 4 legs at corners
79
89
  const legTopY = depth / 2 - frameH;
80
90
  const legCenterY = legTopY - legH / 2;
91
+ const legXPos = isVertical ? (width / 2 - railW / 2) : (width / 2 - legThickness / 2);
92
+ const legZPos = isVertical ? (height / 2 - legThickness / 2) : (height / 2 - railW / 2);
81
93
  for (const xSign of [-1, 1]) {
82
94
  for (const zSign of [-1, 1]) {
83
- const lx = xSign * (width / 2 - legThickness / 2);
84
- const lz = zSign * (height / 2 - railW / 2);
85
95
  const leg = new THREE.BoxGeometry(legThickness, legH, legThickness);
86
- leg.translate(lx, legCenterY, lz);
96
+ leg.translate(xSign * legXPos, legCenterY, zSign * legZPos);
87
97
  frameGeometries.push(leg);
88
98
  }
89
99
  }
90
- // Cross-bracing: 다리 사이 연결
100
+ // Cross-bracing
91
101
  const braceH = legThickness * 0.6;
92
102
  const braceW = legThickness * 0.6;
93
- const braceLen = height - railW;
94
103
  const braceY = legTopY - legH * 0.35;
95
- for (const xSign of [-1, 1]) {
96
- const brace = new THREE.BoxGeometry(braceW, braceH, braceLen);
97
- brace.translate(xSign * (width / 2 - legThickness / 2), braceY, 0);
98
- frameGeometries.push(brace);
104
+ // 이송 방향 브레이스
105
+ if (isVertical) {
106
+ for (const xSign of [-1, 1]) {
107
+ const brace = new THREE.BoxGeometry(braceW, braceH, height - legThickness);
108
+ brace.translate(xSign * legXPos, braceY, 0);
109
+ frameGeometries.push(brace);
110
+ }
99
111
  }
100
- // Cross-bracing: 좌우 다리 연결
101
- const braceLenX = width - legThickness;
102
- for (const zSign of [-1, 1]) {
103
- const brace = new THREE.BoxGeometry(braceLenX, braceH, braceW);
104
- brace.translate(0, braceY, zSign * (height / 2 - railW / 2));
105
- frameGeometries.push(brace);
112
+ else {
113
+ for (const zSign of [-1, 1]) {
114
+ const brace = new THREE.BoxGeometry(width - legThickness, braceH, braceW);
115
+ brace.translate(0, braceY, zSign * legZPos);
116
+ frameGeometries.push(brace);
117
+ }
118
+ }
119
+ // 벨트폭 방향 브레이스
120
+ if (isVertical) {
121
+ for (const zSign of [-1, 1]) {
122
+ const brace = new THREE.BoxGeometry(width - railW, braceH, braceW);
123
+ brace.translate(0, braceY, zSign * legZPos);
124
+ frameGeometries.push(brace);
125
+ }
126
+ }
127
+ else {
128
+ for (const xSign of [-1, 1]) {
129
+ const brace = new THREE.BoxGeometry(braceW, braceH, height - railW);
130
+ brace.translate(xSign * legXPos, braceY, 0);
131
+ frameGeometries.push(brace);
132
+ }
106
133
  }
107
134
  const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial);
108
135
  frameMesh.castShadow = true;
@@ -110,13 +137,13 @@ export class Conveyor3D extends RealObjectGroup {
110
137
  this.object3d.add(frameMesh);
111
138
  // --- Rollers or Belt ---
112
139
  if (conveyorType === 1) {
113
- this.buildBelt(width, height, depth, frameH, railW, value);
140
+ this.buildBelt(width, height, depth, frameH, railW, value, isVertical);
114
141
  }
115
142
  else {
116
143
  this.buildRollers(width, height, depth, frameH, railW, rollWidth, isVertical);
117
144
  }
118
145
  // --- Control box (motor housing at one end) ---
119
- this.buildControlBox(width, height, depth, frameH, railW, value);
146
+ this.buildControlBox(width, height, depth, frameH, railW, value, isVertical);
120
147
  }
121
148
  buildRollers(width, height, depth, frameH, railW, rollWidth, isVertical = false) {
122
149
  const rollerRadius = Math.max(rollWidth / 2, 1);
@@ -158,11 +185,13 @@ export class Conveyor3D extends RealObjectGroup {
158
185
  this.object3d.add(rollerMesh);
159
186
  }
160
187
  }
161
- buildBelt(width, height, depth, frameH, railW, value) {
188
+ buildBelt(width, height, depth, frameH, railW, value, isVertical = false) {
162
189
  const drumRadius = frameH * 0.38;
163
- const drumLength = height - railW * 2;
164
190
  const beltY = depth / 2 - frameH / 2;
165
191
  const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0];
192
+ const transportLen = isVertical ? height : width;
193
+ const bw = isVertical ? width : height;
194
+ const drumLength = bw - railW * 2;
166
195
  const rollerMaterial = new THREE.MeshStandardMaterial({
167
196
  color: ROLLER_COLOR,
168
197
  metalness: 0.9,
@@ -171,12 +200,18 @@ export class Conveyor3D extends RealObjectGroup {
171
200
  // Two end drums
172
201
  const drumGeometries = [];
173
202
  const drumInset = drumRadius * 1.5;
174
- const leftDrumX = -width / 2 + drumInset;
175
- const rightDrumX = width / 2 - drumInset;
176
- for (const dx of [leftDrumX, rightDrumX]) {
203
+ const drum1 = -transportLen / 2 + drumInset;
204
+ const drum2 = transportLen / 2 - drumInset;
205
+ for (const dp of [drum1, drum2]) {
177
206
  const drum = new THREE.CylinderGeometry(drumRadius, drumRadius, drumLength, 16);
178
- drum.rotateX(Math.PI / 2);
179
- drum.translate(dx, beltY, 0);
207
+ if (isVertical) {
208
+ drum.rotateZ(Math.PI / 2);
209
+ drum.translate(0, beltY, dp);
210
+ }
211
+ else {
212
+ drum.rotateX(Math.PI / 2);
213
+ drum.translate(dp, beltY, 0);
214
+ }
180
215
  drumGeometries.push(drum);
181
216
  }
182
217
  const drumMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(drumGeometries), rollerMaterial);
@@ -190,49 +225,63 @@ export class Conveyor3D extends RealObjectGroup {
190
225
  roughness: 0.9
191
226
  });
192
227
  // Flat belt top surface spanning between drums
193
- const flatLen = rightDrumX - leftDrumX;
194
- const flatGeo = new THREE.BoxGeometry(flatLen, beltThickness, drumLength);
228
+ const flatLen = drum2 - drum1;
229
+ const flatGeo = isVertical
230
+ ? new THREE.BoxGeometry(drumLength, beltThickness, flatLen)
231
+ : new THREE.BoxGeometry(flatLen, beltThickness, drumLength);
195
232
  const flatMesh = new THREE.Mesh(flatGeo, beltMaterial);
196
233
  flatMesh.position.set(0, beltY + drumRadius, 0);
197
234
  flatMesh.castShadow = true;
198
235
  this.object3d.add(flatMesh);
199
- // Belt wrap around drums (half-torus shape using extruded half-circle)
236
+ // Belt wrap around drums
200
237
  const wrapSegments = 12;
201
- for (const [dx, angleStart] of [
202
- [leftDrumX, Math.PI / 2],
203
- [rightDrumX, -Math.PI / 2]
238
+ for (const [dp, angleStart] of [
239
+ [drum1, Math.PI / 2],
240
+ [drum2, -Math.PI / 2]
204
241
  ]) {
205
242
  const wrapGeometries = [];
206
243
  for (let i = 0; i < wrapSegments; i++) {
207
244
  const a0 = angleStart + (Math.PI * i) / wrapSegments;
208
245
  const a1 = angleStart + (Math.PI * (i + 1)) / wrapSegments;
209
246
  const r = drumRadius + beltThickness / 2;
210
- const x0 = dx + Math.cos(a0) * r;
247
+ const p0 = dp + Math.cos(a0) * r;
211
248
  const y0 = beltY + Math.sin(a0) * r;
212
- const x1 = dx + Math.cos(a1) * r;
249
+ const p1 = dp + Math.cos(a1) * r;
213
250
  const y1 = beltY + Math.sin(a1) * r;
214
- const segLen = Math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2) * 1.05;
215
- const segAngle = Math.atan2(y1 - y0, x1 - x0);
216
- const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength);
217
- seg.rotateZ(segAngle);
218
- seg.translate((x0 + x1) / 2, (y0 + y1) / 2, 0);
219
- wrapGeometries.push(seg);
251
+ const segLen = Math.sqrt((p1 - p0) ** 2 + (y1 - y0) ** 2) * 1.05;
252
+ const segAngle = Math.atan2(y1 - y0, p1 - p0);
253
+ if (isVertical) {
254
+ const seg = new THREE.BoxGeometry(drumLength, beltThickness, segLen);
255
+ seg.rotateX(-segAngle);
256
+ seg.translate(0, (y0 + y1) / 2, (p0 + p1) / 2);
257
+ wrapGeometries.push(seg);
258
+ }
259
+ else {
260
+ const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength);
261
+ seg.rotateZ(segAngle);
262
+ seg.translate((p0 + p1) / 2, (y0 + y1) / 2, 0);
263
+ wrapGeometries.push(seg);
264
+ }
220
265
  }
221
266
  const wrapMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(wrapGeometries), beltMaterial);
222
267
  wrapMesh.castShadow = true;
223
268
  this.object3d.add(wrapMesh);
224
269
  }
225
- // Flat belt bottom (return path, slightly below)
226
- const bottomGeo = new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85);
270
+ // Flat belt bottom (return path)
271
+ const bottomGeo = isVertical
272
+ ? new THREE.BoxGeometry(drumLength * 0.85, beltThickness, flatLen)
273
+ : new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85);
227
274
  const bottomMesh = new THREE.Mesh(bottomGeo, beltMaterial);
228
275
  bottomMesh.position.set(0, beltY - drumRadius, 0);
229
276
  this.object3d.add(bottomMesh);
230
277
  }
231
278
  /** Control box (motor/controller housing) + status indicator light */
232
- buildControlBox(width, height, depth, frameH, railW, value) {
233
- const boxW = Math.max(width * 0.08, 4);
279
+ buildControlBox(width, height, depth, frameH, railW, value, isVertical = false) {
280
+ const bw = isVertical ? width : height;
281
+ const tl = isVertical ? height : width;
282
+ const boxW = Math.max(tl * 0.08, 4);
234
283
  const boxH = frameH * 0.7;
235
- const boxD = Math.max(height * 0.2, 4);
284
+ const boxD = Math.max(bw * 0.2, 4);
236
285
  const railY = depth / 2 - frameH / 2;
237
286
  // Box positioned at one end, attached to the side rail
238
287
  const boxMaterial = new THREE.MeshStandardMaterial({
@@ -240,9 +289,16 @@ export class Conveyor3D extends RealObjectGroup {
240
289
  metalness: 0.6,
241
290
  roughness: 0.4
242
291
  });
243
- const boxGeo = new THREE.BoxGeometry(boxW, boxH, boxD);
292
+ const boxGeo = isVertical
293
+ ? new THREE.BoxGeometry(boxD, boxH, boxW)
294
+ : new THREE.BoxGeometry(boxW, boxH, boxD);
244
295
  const boxMesh = new THREE.Mesh(boxGeo, boxMaterial);
245
- boxMesh.position.set(-width / 2 + boxW / 2 + railW, railY - frameH / 2 - boxH / 2 + boxH * 0.15, -height / 2 + railW + boxD / 2);
296
+ if (isVertical) {
297
+ boxMesh.position.set(-width / 2 + railW + boxD / 2, railY - frameH / 2 - boxH / 2 + boxH * 0.15, -height / 2 + boxW / 2 + railW);
298
+ }
299
+ else {
300
+ boxMesh.position.set(-width / 2 + boxW / 2 + railW, railY - frameH / 2 - boxH / 2 + boxH * 0.15, -height / 2 + railW + boxD / 2);
301
+ }
246
302
  boxMesh.castShadow = true;
247
303
  this.object3d.add(boxMesh);
248
304
  // Status indicator light on top of control box
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-3d.js","sourceRoot":"","sources":["../src/conveyor-3d.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,WAAW,GAA2B;IAC1C,CAAC,EAAE,QAAQ,EAAE,OAAO;IACpB,CAAC,EAAE,QAAQ,EAAE,MAAM;IACnB,CAAC,EAAE,QAAQ,EAAE,UAAU;IACvB,CAAC,EAAE,QAAQ,EAAE,OAAO;IACpB,CAAC,EAAE,QAAQ,CAAC,QAAQ;CACrB,CAAA;AAED,MAAM,WAAW,GAAG,QAAQ,CAAA;AAC5B,MAAM,YAAY,GAAG,QAAQ,CAAA;AAC7B,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AAClC,MAAM,eAAe,GAA2B;IAC9C,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;CACZ,CAAA;AAED,MAAM,OAAO,UAAW,SAAQ,eAAe;IAC7C,IAAI,cAAc;QAChB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QACrD,OAAO,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAA;IAC/C,CAAC;IAED,IAAI,QAAQ;QACV,MAAM,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QACzC,OAAO;YACL,CAAC,EAAE,IAAI,CAAC,EAAE;YACV,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC;YACjC,CAAC,EAAE,IAAI,CAAC,EAAE;SACX,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,IAAc,cAAc;QAC1B,OAAO,IAAI,CAAC,cAAc,GAAG,CAAC,CAAA;IAChC,CAAC;IAED,KAAK;QACH,KAAK,CAAC,KAAK,EAAE,CAAA;QAEb,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QACxG,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAA;QAEjC,yEAAyE;QACzE,MAAM,UAAU,GAAG,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI;YAClD,CAAC,CAAC,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK;gBACtC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAA;QAElB,oDAAoD;QACpD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,SAAmB,EAAE,CAAC,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,cAAc,CAAA;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QAE7C,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACnD,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,mDAAmD;QACnD,MAAM,eAAe,GAA2B,EAAE,CAAA;QAClD,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;QAEpC,uBAAuB;QACvB,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;YACxD,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;YAC1D,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;QAED,mCAAmC;QACnC,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,CAAA;QAClC,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,CAAC,CAAA;QAErC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC5B,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,CAAA;gBACjD,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAA;gBAC3C,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;gBACnE,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;gBACjC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,YAAY,GAAG,GAAG,CAAA;QACjC,MAAM,MAAM,GAAG,YAAY,GAAG,GAAG,CAAA;QACjC,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAA;QAC/B,MAAM,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAA;QAEpC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;YAC7D,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAClE,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;QAED,0BAA0B;QAC1B,MAAM,SAAS,GAAG,KAAK,GAAG,YAAY,CAAA;QACtC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;YAC9D,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;YAC5D,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,CAAA;QACrG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAA;QAC3B,SAAS,CAAC,aAAa,GAAG,IAAI,CAAA;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAE5B,0BAA0B;QAC1B,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;QAC5D,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAmB,EAAE,UAAU,CAAC,CAAA;QACzF,CAAC;QAED,iDAAiD;QACjD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAClE,CAAC;IAEO,YAAY,CAAC,KAAa,EAAE,MAAc,EAAE,KAAa,EAAE,MAAc,EAAE,KAAa,EAAE,SAAiB,EAAE,aAAsB,KAAK;QAC9I,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QAC/C,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAA;QACjC,MAAM,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAA;QACzB,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;QAEtC,MAAM,gBAAgB,GAA2B,EAAE,CAAA;QAEnD,IAAI,UAAU,EAAE,CAAC;YACf,gCAAgC;YAChC,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,CAAA;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;YACpD,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;YACpC,MAAM,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;YAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,CAAA;gBAC3B,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,CAAC,CAAA;gBACvF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;gBAC3B,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;gBAC/B,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,gCAAgC;YAChC,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,CAAA;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAA;YACnD,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;YACpC,MAAM,MAAM,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;YAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,CAAA;gBAC3B,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,CAAC,CAAA;gBACvF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;gBAC3B,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;gBAC/B,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,IAAI,CAC/B,mBAAmB,CAAC,eAAe,CAAC,gBAAgB,CAAC,EACrD,IAAI,KAAK,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CACxF,CAAA;YACD,UAAU,CAAC,UAAU,GAAG,IAAI,CAAA;YAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,KAAa,EAAE,MAAc,EAAE,KAAa,EAAE,MAAc,EAAE,KAAa,EAAE,KAAa;QAC1G,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,CAAA;QAChC,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,CAAA;QACrC,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;QAEtD,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACpD,KAAK,EAAE,YAAY;YACnB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QAEF,gBAAgB;QAChB,MAAM,cAAc,GAA2B,EAAE,CAAA;QACjD,MAAM,SAAS,GAAG,UAAU,GAAG,GAAG,CAAA;QAClC,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,SAAS,CAAA;QACxC,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,GAAG,SAAS,CAAA;QAExC,KAAK,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;YAC/E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YACzB,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YAC5B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,CAAA;QACpG,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAA;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAE3B,oEAAoE;QACpE,MAAM,aAAa,GAAG,UAAU,GAAG,IAAI,CAAA;QACvC,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YAClD,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QAEF,+CAA+C;QAC/C,MAAM,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;QACtC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;QACzE,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;QACtD,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,UAAU,EAAE,CAAC,CAAC,CAAA;QAC/C,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAA;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAE3B,uEAAuE;QACvE,MAAM,YAAY,GAAG,EAAE,CAAA;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI;YAC7B,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YACxB,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;SACL,EAAE,CAAC;YACxB,MAAM,cAAc,GAA2B,EAAE,CAAA;YACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,EAAE,GAAG,UAAU,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,YAAY,CAAA;gBACpD,MAAM,EAAE,GAAG,UAAU,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAA;gBAC1D,MAAM,CAAC,GAAG,UAAU,GAAG,aAAa,GAAG,CAAC,CAAA;gBAExC,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBAChC,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBACnC,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBAChC,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBAEnC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAA;gBAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;gBAE7C,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;gBACpE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;gBACrB,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;gBAC9C,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC1B,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,YAAY,CAAC,CAAA;YAClG,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAA;YAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7B,CAAC;QAED,iDAAiD;QACjD,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,GAAG,IAAI,CAAC,CAAA;QAClF,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;QAC1D,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,UAAU,EAAE,CAAC,CAAC,CAAA;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC/B,CAAC;IAED,sEAAsE;IAC9D,eAAe,CACrB,KAAa,EACb,MAAc,EACd,KAAa,EACb,MAAc,EACd,KAAa,EACb,KAAa;QAEb,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QACtC,MAAM,IAAI,GAAG,MAAM,GAAG,GAAG,CAAA;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QACtC,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;QAEpC,uDAAuD;QACvD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACjD,KAAK,EAAE,iBAAiB;YACxB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QACtD,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAClB,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,EAC7B,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAC3C,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,CAC/B,CAAA;QACD,OAAO,CAAC,UAAU,GAAG,IAAI,CAAA;QACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAE1B,+CAA+C;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;QAC1C,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAA;QAC3B,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAA;QAClE,MAAM,cAAc,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAE5C,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACnD,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,aAAa;YACvB,iBAAiB,EAAE,cAAc;YACjC,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;QAC7E,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;QACzD,SAAS,CAAC,QAAQ,CAAC,GAAG,CACpB,OAAO,CAAC,QAAQ,CAAC,CAAC,EAClB,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,EAC1C,OAAO,CAAC,QAAQ,CAAC,CAAC,CACnB,CAAA;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC9B,CAAC;IAED,eAAe,KAAI,CAAC;IAEpB,QAAQ,CAAC,KAA8B,EAAE,MAA+B;QACtE,IAAI,OAAO,IAAI,KAAK,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI,KAAK,IAAI,aAAa,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAC/J,IAAI,CAAC,MAAM,EAAE,CAAA;YACb,OAAM;QACR,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC/B,CAAC;IAED,WAAW,KAAI,CAAC;CACjB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Straight Conveyor 3D Model\n *\n * Roller type: side rails + evenly-spaced cylindrical rollers + 4 legs with cross-bracing\n * Belt type: side rails + two end drums with belt wrapping over them + 4 legs with cross-bracing\n * Both types include a control box at one end and a status indicator light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\nexport class Conveyor3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.min(width, height) * 1.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n /**\n * syncFromObject3D 역변환 시 zPos 오프셋.\n * position.y = zPos + effectiveDepth/2 이므로, 역변환도 effectiveDepth/2를 빼야 한다.\n */\n protected get syncZPosOffset(): number {\n return this.effectiveDepth / 2\n }\n\n build() {\n super.build()\n\n const { width, height, conveyorType = 0, value = 0, rollWidth = 10, orientation } = this.component.state\n const depth = this.effectiveDepth\n\n // orientation: 'horizontal' = 이송 가로, 'vertical' = 이송 세로, '' = auto(긴 방향)\n const isVertical = orientation === 'vertical' ? true\n : orientation === 'horizontal' ? false\n : width < height\n\n // 프레임 두께: rollWidth(롤러 직경)와 동일 단위. 롤러를 감쌀 수 있어야 한다.\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const railW = Math.max(height * 0.06, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Frame: side rails + legs + cross-bracing ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const railY = depth / 2 - frameH / 2\n\n // Side rails (along X)\n for (const zSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(width, frameH, railW)\n rail.translate(0, railY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(rail)\n }\n\n // 4 legs at corners — 레일 바로 아래에 정렬\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n\n for (const xSign of [-1, 1]) {\n for (const zSign of [-1, 1]) {\n const lx = xSign * (width / 2 - legThickness / 2)\n const lz = zSign * (height / 2 - railW / 2)\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(lx, legCenterY, lz)\n frameGeometries.push(leg)\n }\n }\n\n // Cross-bracing: 다리 사이 연결\n const braceH = legThickness * 0.6\n const braceW = legThickness * 0.6\n const braceLen = height - railW\n const braceY = legTopY - legH * 0.35\n\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, braceLen)\n brace.translate(xSign * (width / 2 - legThickness / 2), braceY, 0)\n frameGeometries.push(brace)\n }\n\n // Cross-bracing: 좌우 다리 연결\n const braceLenX = width - legThickness\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceLenX, braceH, braceW)\n brace.translate(0, braceY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(brace)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(width, height, depth, frameH, railW, value)\n } else {\n this.buildRollers(width, height, depth, frameH, railW, rollWidth as number, isVertical)\n }\n\n // --- Control box (motor housing at one end) ---\n this.buildControlBox(width, height, depth, frameH, railW, value)\n }\n\n private buildRollers(width: number, height: number, depth: number, frameH: number, railW: number, rollWidth: number, isVertical: boolean = false) {\n const rollerRadius = Math.max(rollWidth / 2, 1)\n const diameter = rollerRadius * 2\n const step = diameter + 1\n const rollerY = depth / 2 - frameH / 2\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n if (isVertical) {\n // 롤러 축 = X축(가로), 이송 방향 = Z축(세로)\n const rollerLength = width - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(height / step))\n const totalSpan = (count - 1) * step\n const startZ = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const z = startZ + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateZ(Math.PI / 2)\n roller.translate(0, rollerY, z)\n rollerGeometries.push(roller)\n }\n } else {\n // 롤러 축 = Z축(세로), 이송 방향 = X축(가로)\n const rollerLength = height - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(width / step))\n const totalSpan = (count - 1) * step\n const startX = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const x = startX + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateX(Math.PI / 2)\n roller.translate(x, rollerY, 0)\n rollerGeometries.push(roller)\n }\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(rollerGeometries),\n new THREE.MeshStandardMaterial({ color: ROLLER_COLOR, metalness: 0.9, roughness: 0.2 })\n )\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(width: number, height: number, depth: number, frameH: number, railW: number, value: number) {\n const drumRadius = frameH * 0.38\n const drumLength = height - railW * 2\n const beltY = depth / 2 - frameH / 2\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const rollerMaterial = new THREE.MeshStandardMaterial({\n color: ROLLER_COLOR,\n metalness: 0.9,\n roughness: 0.2\n })\n\n // Two end drums\n const drumGeometries: THREE.BufferGeometry[] = []\n const drumInset = drumRadius * 1.5\n const leftDrumX = -width / 2 + drumInset\n const rightDrumX = width / 2 - drumInset\n\n for (const dx of [leftDrumX, rightDrumX]) {\n const drum = new THREE.CylinderGeometry(drumRadius, drumRadius, drumLength, 16)\n drum.rotateX(Math.PI / 2)\n drum.translate(dx, beltY, 0)\n drumGeometries.push(drum)\n }\n\n const drumMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(drumGeometries), rollerMaterial)\n drumMesh.castShadow = true\n this.object3d.add(drumMesh)\n\n // Belt surface: flat top + half-cylinder wraps around each drum end\n const beltThickness = drumRadius * 0.12\n const beltMaterial = new THREE.MeshStandardMaterial({\n color: fillColor,\n metalness: 0.0,\n roughness: 0.9\n })\n\n // Flat belt top surface spanning between drums\n const flatLen = rightDrumX - leftDrumX\n const flatGeo = new THREE.BoxGeometry(flatLen, beltThickness, drumLength)\n const flatMesh = new THREE.Mesh(flatGeo, beltMaterial)\n flatMesh.position.set(0, beltY + drumRadius, 0)\n flatMesh.castShadow = true\n this.object3d.add(flatMesh)\n\n // Belt wrap around drums (half-torus shape using extruded half-circle)\n const wrapSegments = 12\n for (const [dx, angleStart] of [\n [leftDrumX, Math.PI / 2],\n [rightDrumX, -Math.PI / 2]\n ] as [number, number][]) {\n const wrapGeometries: THREE.BufferGeometry[] = []\n for (let i = 0; i < wrapSegments; i++) {\n const a0 = angleStart + (Math.PI * i) / wrapSegments\n const a1 = angleStart + (Math.PI * (i + 1)) / wrapSegments\n const r = drumRadius + beltThickness / 2\n\n const x0 = dx + Math.cos(a0) * r\n const y0 = beltY + Math.sin(a0) * r\n const x1 = dx + Math.cos(a1) * r\n const y1 = beltY + Math.sin(a1) * r\n\n const segLen = Math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2) * 1.05\n const segAngle = Math.atan2(y1 - y0, x1 - x0)\n\n const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength)\n seg.rotateZ(segAngle)\n seg.translate((x0 + x1) / 2, (y0 + y1) / 2, 0)\n wrapGeometries.push(seg)\n }\n const wrapMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(wrapGeometries), beltMaterial)\n wrapMesh.castShadow = true\n this.object3d.add(wrapMesh)\n }\n\n // Flat belt bottom (return path, slightly below)\n const bottomGeo = new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85)\n const bottomMesh = new THREE.Mesh(bottomGeo, beltMaterial)\n bottomMesh.position.set(0, beltY - drumRadius, 0)\n this.object3d.add(bottomMesh)\n }\n\n /** Control box (motor/controller housing) + status indicator light */\n private buildControlBox(\n width: number,\n height: number,\n depth: number,\n frameH: number,\n railW: number,\n value: number\n ) {\n const boxW = Math.max(width * 0.08, 4)\n const boxH = frameH * 0.7\n const boxD = Math.max(height * 0.2, 4)\n const railY = depth / 2 - frameH / 2\n\n // Box positioned at one end, attached to the side rail\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = new THREE.BoxGeometry(boxW, boxH, boxD)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n boxMesh.position.set(\n -width / 2 + boxW / 2 + railW,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + railW + boxD / 2\n )\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status indicator light on top of control box\n const lightR = Math.min(boxW, boxD) * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n const lightIntensity = value > 0 ? 1.5 : 0.2\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: lightIntensity,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(\n boxMesh.position.x,\n boxMesh.position.y + boxH / 2 + lightH / 2,\n boxMesh.position.z\n )\n this.object3d.add(lightMesh)\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'conveyorType' in after || 'rollWidth' in after || 'orientation' in after || 'width' in after || 'height' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
1
+ {"version":3,"file":"conveyor-3d.js","sourceRoot":"","sources":["../src/conveyor-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Straight Conveyor 3D Model\n *\n * Roller type: side rails + evenly-spaced cylindrical rollers + 4 legs with cross-bracing\n * Belt type: side rails + two end drums with belt wrapping over them + 4 legs with cross-bracing\n * Both types include a control box at one end and a status indicator light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\nexport class Conveyor3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.min(width, height) * 1.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n /**\n * syncFromObject3D 역변환 시 zPos 오프셋.\n * position.y = zPos + effectiveDepth/2 이므로, 역변환도 effectiveDepth/2를 빼야 한다.\n */\n protected get syncZPosOffset(): number {\n return this.effectiveDepth / 2\n }\n\n build() {\n super.build()\n\n const { width, height, conveyorType = 0, value = 0, rollWidth = 10, orientation } = this.component.state\n const depth = this.effectiveDepth\n\n // orientation: 'horizontal' = 이송 가로, 'vertical' = 이송 세로, '' = auto(긴 방향)\n const isVertical = orientation === 'vertical' ? true\n : orientation === 'horizontal' ? false\n : width < height\n\n // 프레임 두께: rollWidth(롤러 직경)와 동일 단위. 롤러를 감쌀 수 있어야 한다.\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const beltWidth = isVertical ? width : height\n const railW = Math.max(beltWidth * 0.06, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Frame: side rails + legs + cross-bracing ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const railY = depth / 2 - frameH / 2\n\n // Side rails — 이송 방향을 따라, 벨트 양측에 배치\n if (isVertical) {\n for (const xSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(railW, frameH, height)\n rail.translate(xSign * (width / 2 - railW / 2), railY, 0)\n frameGeometries.push(rail)\n }\n } else {\n for (const zSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(width, frameH, railW)\n rail.translate(0, railY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(rail)\n }\n }\n\n // 4 legs at corners\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n const legXPos = isVertical ? (width / 2 - railW / 2) : (width / 2 - legThickness / 2)\n const legZPos = isVertical ? (height / 2 - legThickness / 2) : (height / 2 - railW / 2)\n\n for (const xSign of [-1, 1]) {\n for (const zSign of [-1, 1]) {\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(xSign * legXPos, legCenterY, zSign * legZPos)\n frameGeometries.push(leg)\n }\n }\n\n // Cross-bracing\n const braceH = legThickness * 0.6\n const braceW = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n\n // 이송 방향 브레이스\n if (isVertical) {\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, height - legThickness)\n brace.translate(xSign * legXPos, braceY, 0)\n frameGeometries.push(brace)\n }\n } else {\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - legThickness, braceH, braceW)\n brace.translate(0, braceY, zSign * legZPos)\n frameGeometries.push(brace)\n }\n }\n\n // 벨트폭 방향 브레이스\n if (isVertical) {\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - railW, braceH, braceW)\n brace.translate(0, braceY, zSign * legZPos)\n frameGeometries.push(brace)\n }\n } else {\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, height - railW)\n brace.translate(xSign * legXPos, braceY, 0)\n frameGeometries.push(brace)\n }\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(width, height, depth, frameH, railW, value, isVertical)\n } else {\n this.buildRollers(width, height, depth, frameH, railW, rollWidth as number, isVertical)\n }\n\n // --- Control box (motor housing at one end) ---\n this.buildControlBox(width, height, depth, frameH, railW, value, isVertical)\n }\n\n private buildRollers(width: number, height: number, depth: number, frameH: number, railW: number, rollWidth: number, isVertical: boolean = false) {\n const rollerRadius = Math.max(rollWidth / 2, 1)\n const diameter = rollerRadius * 2\n const step = diameter + 1\n const rollerY = depth / 2 - frameH / 2\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n if (isVertical) {\n // 롤러 축 = X축(가로), 이송 방향 = Z축(세로)\n const rollerLength = width - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(height / step))\n const totalSpan = (count - 1) * step\n const startZ = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const z = startZ + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateZ(Math.PI / 2)\n roller.translate(0, rollerY, z)\n rollerGeometries.push(roller)\n }\n } else {\n // 롤러 축 = Z축(세로), 이송 방향 = X축(가로)\n const rollerLength = height - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(width / step))\n const totalSpan = (count - 1) * step\n const startX = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const x = startX + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateX(Math.PI / 2)\n roller.translate(x, rollerY, 0)\n rollerGeometries.push(roller)\n }\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(rollerGeometries),\n new THREE.MeshStandardMaterial({ color: ROLLER_COLOR, metalness: 0.9, roughness: 0.2 })\n )\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(width: number, height: number, depth: number, frameH: number, railW: number, value: number, isVertical: boolean = false) {\n const drumRadius = frameH * 0.38\n const beltY = depth / 2 - frameH / 2\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const transportLen = isVertical ? height : width\n const bw = isVertical ? width : height\n const drumLength = bw - railW * 2\n\n const rollerMaterial = new THREE.MeshStandardMaterial({\n color: ROLLER_COLOR,\n metalness: 0.9,\n roughness: 0.2\n })\n\n // Two end drums\n const drumGeometries: THREE.BufferGeometry[] = []\n const drumInset = drumRadius * 1.5\n const drum1 = -transportLen / 2 + drumInset\n const drum2 = transportLen / 2 - drumInset\n\n for (const dp of [drum1, drum2]) {\n const drum = new THREE.CylinderGeometry(drumRadius, drumRadius, drumLength, 16)\n if (isVertical) {\n drum.rotateZ(Math.PI / 2)\n drum.translate(0, beltY, dp)\n } else {\n drum.rotateX(Math.PI / 2)\n drum.translate(dp, beltY, 0)\n }\n drumGeometries.push(drum)\n }\n\n const drumMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(drumGeometries), rollerMaterial)\n drumMesh.castShadow = true\n this.object3d.add(drumMesh)\n\n // Belt surface: flat top + half-cylinder wraps around each drum end\n const beltThickness = drumRadius * 0.12\n const beltMaterial = new THREE.MeshStandardMaterial({\n color: fillColor,\n metalness: 0.0,\n roughness: 0.9\n })\n\n // Flat belt top surface spanning between drums\n const flatLen = drum2 - drum1\n const flatGeo = isVertical\n ? new THREE.BoxGeometry(drumLength, beltThickness, flatLen)\n : new THREE.BoxGeometry(flatLen, beltThickness, drumLength)\n const flatMesh = new THREE.Mesh(flatGeo, beltMaterial)\n flatMesh.position.set(0, beltY + drumRadius, 0)\n flatMesh.castShadow = true\n this.object3d.add(flatMesh)\n\n // Belt wrap around drums\n const wrapSegments = 12\n for (const [dp, angleStart] of [\n [drum1, Math.PI / 2],\n [drum2, -Math.PI / 2]\n ] as [number, number][]) {\n const wrapGeometries: THREE.BufferGeometry[] = []\n for (let i = 0; i < wrapSegments; i++) {\n const a0 = angleStart + (Math.PI * i) / wrapSegments\n const a1 = angleStart + (Math.PI * (i + 1)) / wrapSegments\n const r = drumRadius + beltThickness / 2\n\n const p0 = dp + Math.cos(a0) * r\n const y0 = beltY + Math.sin(a0) * r\n const p1 = dp + Math.cos(a1) * r\n const y1 = beltY + Math.sin(a1) * r\n\n const segLen = Math.sqrt((p1 - p0) ** 2 + (y1 - y0) ** 2) * 1.05\n const segAngle = Math.atan2(y1 - y0, p1 - p0)\n\n if (isVertical) {\n const seg = new THREE.BoxGeometry(drumLength, beltThickness, segLen)\n seg.rotateX(-segAngle)\n seg.translate(0, (y0 + y1) / 2, (p0 + p1) / 2)\n wrapGeometries.push(seg)\n } else {\n const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength)\n seg.rotateZ(segAngle)\n seg.translate((p0 + p1) / 2, (y0 + y1) / 2, 0)\n wrapGeometries.push(seg)\n }\n }\n const wrapMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(wrapGeometries), beltMaterial)\n wrapMesh.castShadow = true\n this.object3d.add(wrapMesh)\n }\n\n // Flat belt bottom (return path)\n const bottomGeo = isVertical\n ? new THREE.BoxGeometry(drumLength * 0.85, beltThickness, flatLen)\n : new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85)\n const bottomMesh = new THREE.Mesh(bottomGeo, beltMaterial)\n bottomMesh.position.set(0, beltY - drumRadius, 0)\n this.object3d.add(bottomMesh)\n }\n\n /** Control box (motor/controller housing) + status indicator light */\n private buildControlBox(\n width: number,\n height: number,\n depth: number,\n frameH: number,\n railW: number,\n value: number,\n isVertical: boolean = false\n ) {\n const bw = isVertical ? width : height\n const tl = isVertical ? height : width\n const boxW = Math.max(tl * 0.08, 4)\n const boxH = frameH * 0.7\n const boxD = Math.max(bw * 0.2, 4)\n const railY = depth / 2 - frameH / 2\n\n // Box positioned at one end, attached to the side rail\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = isVertical\n ? new THREE.BoxGeometry(boxD, boxH, boxW)\n : new THREE.BoxGeometry(boxW, boxH, boxD)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n if (isVertical) {\n boxMesh.position.set(\n -width / 2 + railW + boxD / 2,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + boxW / 2 + railW\n )\n } else {\n boxMesh.position.set(\n -width / 2 + boxW / 2 + railW,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + railW + boxD / 2\n )\n }\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status indicator light on top of control box\n const lightR = Math.min(boxW, boxD) * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n const lightIntensity = value > 0 ? 1.5 : 0.2\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: lightIntensity,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(\n boxMesh.position.x,\n boxMesh.position.y + boxH / 2 + lightH / 2,\n boxMesh.position.z\n )\n this.object3d.add(lightMesh)\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'conveyorType' in after || 'rollWidth' in after || 'orientation' in after || 'width' in after || 'height' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
@@ -6,7 +6,7 @@ interface RollerMixin {
6
6
  declare const MixinPolygon: typeof Component & (new (...args: any[]) => RollerMixin);
7
7
  export default class ConveyorJoinTrapezoid extends MixinPolygon {
8
8
  get nature(): ComponentNature;
9
- is3dish(): boolean;
9
+ get anchors(): never[];
10
10
  buildRealObject(): RealObject | undefined;
11
11
  render(context: CanvasRenderingContext2D): void;
12
12
  }
@@ -60,8 +60,8 @@ let ConveyorJoinTrapezoid = class ConveyorJoinTrapezoid extends MixinPolygon {
60
60
  get nature() {
61
61
  return NATURE;
62
62
  }
63
- is3dish() {
64
- return true;
63
+ get anchors() {
64
+ return [];
65
65
  }
66
66
  buildRealObject() {
67
67
  return new ConveyorJoinTrapezoid3D(this);
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-join-trapezoid.js","sourceRoot":"","sources":["../src/conveyor-join-trapezoid.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqC,OAAO,EAAc,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE/G;;GAEG;AACH,OAAO,WAAW,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAEzE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP;wBACE,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,CAAC;qBACT;oBACD;wBACE,OAAO,EAAE,MAAM;wBACf,KAAK,EAAE,CAAC;qBACT;iBACF;aACF;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,yCAAyC;CAChD,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAQpB,sBAAsB;AACtB,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAwE,CAAA;AAGjG,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,YAAY;IAC7D,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,uBAAuB,CAAC,IAAW,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAC/C,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;CACF,CAAA;AAjBoB,qBAAqB;IADzC,cAAc,CAAC,yBAAyB,CAAC;GACrB,qBAAqB,CAiBzC;eAjBoB,qBAAqB","sourcesContent":["import { Class, Component, ComponentNature, Polygon, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoinTrapezoid3D } from './conveyor-join-trapezoid-3d.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join-trapezoid'\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 3\nconst STAT_ERROR = 4\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinPolygon = MixinRoller(Polygon) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join-trapezoid')\nexport default class ConveyorJoinTrapezoid extends MixinPolygon {\n get nature() {\n return NATURE\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoinTrapezoid3D(this as any)\n }\n\n render(context: CanvasRenderingContext2D) {\n this.getState('animated') && this.animOnState()\n super.render(context)\n }\n}\n"]}
1
+ {"version":3,"file":"conveyor-join-trapezoid.js","sourceRoot":"","sources":["../src/conveyor-join-trapezoid.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqC,OAAO,EAAc,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE/G;;GAEG;AACH,OAAO,WAAW,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAEzE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP;wBACE,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,CAAC;qBACT;oBACD;wBACE,OAAO,EAAE,MAAM;wBACf,KAAK,EAAE,CAAC;qBACT;iBACF;aACF;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,yCAAyC;CAChD,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAQpB,sBAAsB;AACtB,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAwE,CAAA;AAGjG,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,YAAY;IAC7D,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IACD,eAAe;QACb,OAAO,IAAI,uBAAuB,CAAC,IAAW,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAC/C,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;CACF,CAAA;AAhBoB,qBAAqB;IADzC,cAAc,CAAC,yBAAyB,CAAC;GACrB,qBAAqB,CAgBzC;eAhBoB,qBAAqB","sourcesContent":["import { Class, Component, ComponentNature, Polygon, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoinTrapezoid3D } from './conveyor-join-trapezoid-3d.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join-trapezoid'\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 3\nconst STAT_ERROR = 4\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinPolygon = MixinRoller(Polygon) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join-trapezoid')\nexport default class ConveyorJoinTrapezoid extends MixinPolygon {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoinTrapezoid3D(this as any)\n }\n\n render(context: CanvasRenderingContext2D) {\n this.getState('animated') && this.animOnState()\n super.render(context)\n }\n}\n"]}
@@ -6,8 +6,8 @@ interface RollerMixin {
6
6
  declare const MixinDonut: typeof Component & (new (...args: any[]) => RollerMixin);
7
7
  export default class ConveyorJoin extends MixinDonut {
8
8
  get nature(): ComponentNature;
9
+ get anchors(): never[];
9
10
  get fillStyle(): string;
10
- is3dish(): boolean;
11
11
  buildRealObject(): RealObject | undefined;
12
12
  contains(x: number, y: number): boolean;
13
13
  render(ctx: CanvasRenderingContext2D): void;
@@ -124,14 +124,14 @@ let ConveyorJoin = class ConveyorJoin extends MixinDonut {
124
124
  get nature() {
125
125
  return NATURE;
126
126
  }
127
+ get anchors() {
128
+ return [];
129
+ }
127
130
  // mixin의 패턴 fillStyle을 오버라이드 — 방사선 롤러를 직접 그리므로 단색 fill 사용
128
131
  get fillStyle() {
129
132
  const FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b'];
130
133
  return FILL_STYLES[this.value || 0] || FILL_STYLES[0];
131
134
  }
132
- is3dish() {
133
- return true;
134
- }
135
135
  buildRealObject() {
136
136
  return new ConveyorJoin3D(this);
137
137
  }
@@ -145,8 +145,14 @@ let ConveyorJoin = class ConveyorJoin extends MixinDonut {
145
145
  const ratioy = (y - cy) / ((ry / 100) * ratio * 2 - 0.5);
146
146
  if (normx * normx + normy * normy < 0.25 && ratiox * ratiox + ratioy * ratioy > 0.25) {
147
147
  const angle = normalizeAngle(Math.atan2(-normy, normx) - Math.PI / 2);
148
- if (angle >= startAngle && angle <= endAngle) {
149
- return true;
148
+ if (startAngle <= endAngle) {
149
+ if (angle >= startAngle && angle <= endAngle)
150
+ return true;
151
+ }
152
+ else {
153
+ // wraparound: startAngle > endAngle (예: π → 0)
154
+ if (angle >= startAngle || angle <= endAngle)
155
+ return true;
150
156
  }
151
157
  }
152
158
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-join.js","sourceRoot":"","sources":["../src/conveyor-join.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, Donut, POSITION, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoin3D } from './conveyor-join-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'angle',\n label: 'start-angle',\n name: 'startAngle'\n },\n {\n type: 'angle',\n label: 'end-angle',\n name: 'endAngle'\n },\n {\n type: 'number',\n label: 'ratio',\n name: 'ratio'\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join'\n}\n\nvar controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy, rx, ry, startAngle, endAngle } = component.model\n\n var { x, y } = component.transcoordP2S(point.x, point.y)\n\n const angle = (startAngle + endAngle) / 2\n\n /* 원점으로부터 최대 거리 */\n const dx = Math.abs(rx * Math.sin(angle))\n const dy = Math.abs(ry * Math.cos(angle))\n const distance = Math.sqrt(dx * dx + dy * dy)\n\n /* 원점으로부터 현재 컨트롤 위치까지의 거리 */\n const px = Math.abs(cx - x)\n const py = Math.abs(cy - y)\n const pdistance = Math.sqrt(px * px + py * py)\n\n var ratio = (pdistance / distance) * 100\n\n ratio = ratio >= 100 || ratio <= -100 ? 100 : Math.abs(ratio)\n\n component.set({ ratio })\n }\n}\n\nvar antiClockWiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0 && theta <= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0 && theta >= -Math.PI / 2) theta = -Math.PI / 2\n\n const startAngle = (-theta + Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n\n component.set({ startAngle })\n }\n}\n\nvar clockwiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0) if (theta >= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0) if (theta <= -Math.PI / 2) theta = -Math.PI / 2\n\n var endAngle = -theta + Math.PI / 2\n\n component.set({ endAngle })\n }\n}\n\nfunction normalizeAngle(angle: number): number {\n angle = angle % (2 * Math.PI)\n if (angle <= -Math.PI) {\n angle += 2 * Math.PI\n } else if (angle > Math.PI) {\n angle -= 2 * Math.PI\n }\n return angle\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinDonut = MixinRoller(Donut) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join')\nexport default class ConveyorJoin extends MixinDonut {\n get nature() {\n return NATURE\n }\n\n // mixin의 패턴 fillStyle을 오버라이드 — 방사선 롤러를 직접 그리므로 단색 fill 사용\n get fillStyle() {\n const FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b']\n return FILL_STYLES[(this as any).value || 0] || FILL_STYLES[0]\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoin3D(this as any)\n }\n\n contains(x: number, y: number) {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n rx = Math.abs(rx)\n ry = Math.abs(ry)\n\n const normx = (x - cx) / (rx * 2 - 0.5)\n const normy = (y - cy) / (ry * 2 - 0.5)\n const ratiox = (x - cx) / ((rx / 100) * ratio * 2 - 0.5)\n const ratioy = (y - cy) / ((ry / 100) * ratio * 2 - 0.5)\n\n if (normx * normx + normy * normy < 0.25 && ratiox * ratiox + ratioy * ratioy > 0.25) {\n const angle = normalizeAngle(Math.atan2(-normy, normx) - Math.PI / 2)\n\n if (angle >= startAngle && angle <= endAngle) {\n return true\n }\n }\n\n return false\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, animated = false, rollWidth = 10, conveyorType = 0 } = this.state\n\n animated && this.animOnState()\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n // 2D 각도 변환\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n // 호 영역 path\n ctx.beginPath()\n ctx.ellipse(cx, cy, outerRx, outerRy, 0, sa, ea)\n ctx.ellipse(cx, cy, innerRx, innerRy, 0, ea, sa, true)\n ctx.closePath()\n\n // 롤러 타입일 때: base class가 단색 fill 후, 여기서 방사선 롤러 라인 추가\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n\n const { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, rollWidth = 10, conveyorType = 0 } = this.state\n if (conveyorType === 1) return // 벨트 타입은 패턴 사용\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n const STROKE_STYLES = ['#999', '#87b1db', '#87b1db', '#d96f21', '#a73928']\n const v = (this as any).value || 0\n\n const midR = (outerRx + innerRx) / 2\n const arcLen = midR * Math.abs(ea - sa)\n const spacing = Math.max(rollWidth as number, 5)\n const count = Math.max(1, Math.floor(arcLen / spacing))\n\n ctx.save()\n ctx.strokeStyle = STROKE_STYLES[v] || STROKE_STYLES[0]\n ctx.lineWidth = Math.max(0.5, spacing * 0.12)\n\n for (let i = 1; i <= count; i++) {\n const t = i / (count + 1)\n const angle = sa + (ea - sa) * t\n\n ctx.beginPath()\n ctx.moveTo(outerRx * Math.cos(angle) + cx, outerRy * Math.sin(angle) + cy)\n ctx.lineTo(innerRx * Math.cos(angle) + cx, innerRy * Math.sin(angle) + cy)\n ctx.stroke()\n }\n ctx.restore()\n }\n\n get controls() {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n\n var controls = []\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(startAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(startAngle),\n handler: antiClockWiseControlHandler\n })\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(endAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(endAngle),\n handler: clockwiseControlHandler\n })\n\n const angle = (startAngle + endAngle) / 2\n controls.push({\n x: cx + ((rx * ratio) / 100) * Math.sin(angle),\n y: cy - ((ry * ratio) / 100) * Math.cos(angle),\n handler: controlHandler\n })\n\n return controls\n }\n}\n"]}
1
+ {"version":3,"file":"conveyor-join.js","sourceRoot":"","sources":["../src/conveyor-join.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, Donut, POSITION, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoin3D } from './conveyor-join-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'angle',\n label: 'start-angle',\n name: 'startAngle'\n },\n {\n type: 'angle',\n label: 'end-angle',\n name: 'endAngle'\n },\n {\n type: 'number',\n label: 'ratio',\n name: 'ratio'\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join'\n}\n\nvar controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy, rx, ry, startAngle, endAngle } = component.model\n\n var { x, y } = component.transcoordP2S(point.x, point.y)\n\n const angle = (startAngle + endAngle) / 2\n\n /* 원점으로부터 최대 거리 */\n const dx = Math.abs(rx * Math.sin(angle))\n const dy = Math.abs(ry * Math.cos(angle))\n const distance = Math.sqrt(dx * dx + dy * dy)\n\n /* 원점으로부터 현재 컨트롤 위치까지의 거리 */\n const px = Math.abs(cx - x)\n const py = Math.abs(cy - y)\n const pdistance = Math.sqrt(px * px + py * py)\n\n var ratio = (pdistance / distance) * 100\n\n ratio = ratio >= 100 || ratio <= -100 ? 100 : Math.abs(ratio)\n\n component.set({ ratio })\n }\n}\n\nvar antiClockWiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0 && theta <= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0 && theta >= -Math.PI / 2) theta = -Math.PI / 2\n\n const startAngle = (-theta + Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n\n component.set({ startAngle })\n }\n}\n\nvar clockwiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0) if (theta >= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0) if (theta <= -Math.PI / 2) theta = -Math.PI / 2\n\n var endAngle = -theta + Math.PI / 2\n\n component.set({ endAngle })\n }\n}\n\nfunction normalizeAngle(angle: number): number {\n angle = angle % (2 * Math.PI)\n if (angle <= -Math.PI) {\n angle += 2 * Math.PI\n } else if (angle > Math.PI) {\n angle -= 2 * Math.PI\n }\n return angle\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinDonut = MixinRoller(Donut) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join')\nexport default class ConveyorJoin extends MixinDonut {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n // mixin의 패턴 fillStyle을 오버라이드 — 방사선 롤러를 직접 그리므로 단색 fill 사용\n get fillStyle() {\n const FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b']\n return FILL_STYLES[(this as any).value || 0] || FILL_STYLES[0]\n }\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoin3D(this as any)\n }\n\n contains(x: number, y: number) {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n rx = Math.abs(rx)\n ry = Math.abs(ry)\n\n const normx = (x - cx) / (rx * 2 - 0.5)\n const normy = (y - cy) / (ry * 2 - 0.5)\n const ratiox = (x - cx) / ((rx / 100) * ratio * 2 - 0.5)\n const ratioy = (y - cy) / ((ry / 100) * ratio * 2 - 0.5)\n\n if (normx * normx + normy * normy < 0.25 && ratiox * ratiox + ratioy * ratioy > 0.25) {\n const angle = normalizeAngle(Math.atan2(-normy, normx) - Math.PI / 2)\n\n if (startAngle <= endAngle) {\n if (angle >= startAngle && angle <= endAngle) return true\n } else {\n // wraparound: startAngle > endAngle (예: π → 0)\n if (angle >= startAngle || angle <= endAngle) return true\n }\n }\n\n return false\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, animated = false, rollWidth = 10, conveyorType = 0 } = this.state\n\n animated && this.animOnState()\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n // 2D 각도 변환\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n // 호 영역 path\n ctx.beginPath()\n ctx.ellipse(cx, cy, outerRx, outerRy, 0, sa, ea)\n ctx.ellipse(cx, cy, innerRx, innerRy, 0, ea, sa, true)\n ctx.closePath()\n\n // 롤러 타입일 때: base class가 단색 fill 후, 여기서 방사선 롤러 라인 추가\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n\n const { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, rollWidth = 10, conveyorType = 0 } = this.state\n if (conveyorType === 1) return // 벨트 타입은 패턴 사용\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n const STROKE_STYLES = ['#999', '#87b1db', '#87b1db', '#d96f21', '#a73928']\n const v = (this as any).value || 0\n\n const midR = (outerRx + innerRx) / 2\n const arcLen = midR * Math.abs(ea - sa)\n const spacing = Math.max(rollWidth as number, 5)\n const count = Math.max(1, Math.floor(arcLen / spacing))\n\n ctx.save()\n ctx.strokeStyle = STROKE_STYLES[v] || STROKE_STYLES[0]\n ctx.lineWidth = Math.max(0.5, spacing * 0.12)\n\n for (let i = 1; i <= count; i++) {\n const t = i / (count + 1)\n const angle = sa + (ea - sa) * t\n\n ctx.beginPath()\n ctx.moveTo(outerRx * Math.cos(angle) + cx, outerRy * Math.sin(angle) + cy)\n ctx.lineTo(innerRx * Math.cos(angle) + cx, innerRy * Math.sin(angle) + cy)\n ctx.stroke()\n }\n ctx.restore()\n }\n\n get controls() {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n\n var controls = []\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(startAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(startAngle),\n handler: antiClockWiseControlHandler\n })\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(endAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(endAngle),\n handler: clockwiseControlHandler\n })\n\n const angle = (startAngle + endAngle) / 2\n controls.push({\n x: cx + ((rx * ratio) / 100) * Math.sin(angle),\n y: cy - ((ry * ratio) / 100) * Math.cos(angle),\n handler: controlHandler\n })\n\n return controls\n }\n}\n"]}
@@ -7,7 +7,8 @@ declare const MixinShape: typeof Component & (new (...args: any[]) => RollerMixi
7
7
  export default class Conveyor extends MixinShape {
8
8
  get nature(): ComponentNature;
9
9
  render(ctx: CanvasRenderingContext2D): void;
10
- is3dish(): boolean;
10
+ onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
11
+ get anchors(): never[];
11
12
  buildRealObject(): RealObject | undefined;
12
13
  }
13
14
  export {};
package/dist/conveyor.js CHANGED
@@ -74,8 +74,20 @@ let Conveyor = class Conveyor extends MixinShape {
74
74
  ctx.beginPath();
75
75
  ctx.rect(left, top, width, height);
76
76
  }
77
- is3dish() {
78
- return true;
77
+ onchange(after, before) {
78
+ if ('orientation' in after || 'conveyorType' in after || 'rollWidth' in after || 'value' in after) {
79
+ delete this._roller_pattern;
80
+ delete this._roller_pattern_v;
81
+ delete this._pattern_image;
82
+ delete this._pattern_image_origin;
83
+ this.clearCache('fillStyle');
84
+ this.clearCache('conveyorType');
85
+ this.invalidate();
86
+ }
87
+ super.onchange(after, before);
88
+ }
89
+ get anchors() {
90
+ return [];
79
91
  }
80
92
  buildRealObject() {
81
93
  return new Conveyor3D(this);
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor.js","sourceRoot":"","sources":["../src/conveyor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,WAAW,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAQ7C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP;wBACE,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,CAAC;qBACT;oBACD;wBACE,OAAO,EAAE,MAAM;wBACf,KAAK,EAAE,CAAC;qBACT;iBACF;aACF;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,sBAAsB;YAC7B,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC9B,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;oBAC9C,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;iBAC3C;aACF;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,0BAA0B;CACjC,CAAA;AAED,sBAAsB;AACtB,MAAM,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAwE,CAAA;AAIvG,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,UAAU;IAC9C,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE/D,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAE9B,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IACpC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,UAAU,CAAC,IAAW,CAAC,CAAA;IACpC,CAAC;CACF,CAAA;AArBoB,QAAQ;IAF5B,cAAc,CAAC,UAAU,CAAC;IAC1B,cAAc,CAAC,eAAe,CAAC;GACX,QAAQ,CAqB5B;eArBoB,QAAQ","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { Conveyor3D } from './conveyor-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'select',\n label: 'conveyor-orientation',\n name: 'orientation',\n property: {\n options: [\n { display: 'Auto', value: '' },\n { display: 'Horizontal', value: 'horizontal' },\n { display: 'Vertical', value: 'vertical' }\n ]\n }\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinRoller(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor')\n@sceneComponent('conveyor-belt')\nexport default class Conveyor extends MixinShape {\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated = false } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Conveyor3D(this as any)\n }\n}\n"]}
1
+ {"version":3,"file":"conveyor.js","sourceRoot":"","sources":["../src/conveyor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { Conveyor3D } from './conveyor-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'select',\n label: 'conveyor-orientation',\n name: 'orientation',\n property: {\n options: [\n { display: 'Auto', value: '' },\n { display: 'Horizontal', value: 'horizontal' },\n { display: 'Vertical', value: 'vertical' }\n ]\n }\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinRoller(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor')\n@sceneComponent('conveyor-belt')\nexport default class Conveyor extends MixinShape {\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated = false } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('orientation' in after || 'conveyorType' in after || 'rollWidth' in after || 'value' in after) {\n delete (this as any)._roller_pattern\n delete (this as any)._roller_pattern_v\n delete (this as any)._pattern_image\n delete (this as any)._pattern_image_origin\n ;(this as any).clearCache('fillStyle')\n ;(this as any).clearCache('conveyorType')\n this.invalidate()\n }\n super.onchange(after, before)\n }\n\n get anchors() {\n return []\n }\n buildRealObject(): RealObject | undefined {\n return new Conveyor3D(this as any)\n }\n}\n"]}
@@ -38,6 +38,13 @@ function pattern_for_belt_type(component) {
38
38
  context.stroke();
39
39
  return component._roller_pattern;
40
40
  }
41
+ function isVerticalOrientation(component) {
42
+ const { orientation } = component.model || {};
43
+ const { width, height } = component.bounds;
44
+ return orientation === 'vertical' ? true
45
+ : orientation === 'horizontal' ? false
46
+ : width < height;
47
+ }
41
48
  function pattern_for_roller_type(component) {
42
49
  var { height } = component.bounds;
43
50
  var { rollWidth = 10, animated } = component.model;
@@ -80,12 +87,80 @@ function pattern_for_roller_type(component) {
80
87
  }
81
88
  return component._roller_pattern;
82
89
  }
90
+ function pattern_for_roller_type_vertical(component) {
91
+ var { width } = component.bounds;
92
+ var { rollWidth = 10, animated } = component.model;
93
+ var rw = Math.max(rollWidth, 1);
94
+ var color = FILL_STYLES[component.value] || FILL_STYLES[0];
95
+ var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0];
96
+ var lineWidth = Math.min(1, rw / 10);
97
+ rw += lineWidth * 2;
98
+ var gap = Math.floor((rw * 2) / 3);
99
+ if (!component._roller_pattern_v)
100
+ component._roller_pattern_v = document.createElement('canvas');
101
+ component._roller_pattern_v.width = width;
102
+ component._roller_pattern_v.height = rw + gap;
103
+ var ctx = component._roller_pattern_v.getContext('2d');
104
+ ctx.beginPath();
105
+ ctx.fillStyle = color;
106
+ ctx.strokeStyle = stroke;
107
+ ctx.lineWidth = lineWidth;
108
+ // 가로 롤러: 좌측 반타원 + 본체 + 우측 반타원
109
+ var cy = lineWidth + rw / 2;
110
+ ctx.ellipse(rw / 4 + lineWidth, cy, rw / 4, rw / 2, 0, Math.PI / 2, -Math.PI / 2, true);
111
+ ctx.lineTo(width - rw / 4 - lineWidth, lineWidth);
112
+ ctx.ellipse(width - rw / 4 - lineWidth, cy, rw / 4, rw / 2, 0, -Math.PI / 2, Math.PI / 2, true);
113
+ ctx.lineTo(rw / 4 + lineWidth, lineWidth + rw);
114
+ ctx.fill();
115
+ ctx.stroke();
116
+ if (animated) {
117
+ ctx.globalAlpha = 0.2;
118
+ ctx.lineWidth = rw / 3;
119
+ var y_for_roll = (component._step || 0) % rw;
120
+ if (component.value == 2)
121
+ y_for_roll = rw - y_for_roll;
122
+ ctx.beginPath();
123
+ ctx.moveTo(rw / 4, cy - rw / 2 + y_for_roll);
124
+ ctx.lineTo(width - rw / 4, cy - rw / 2 + y_for_roll);
125
+ ctx.stroke();
126
+ }
127
+ return component._roller_pattern_v;
128
+ }
129
+ function pattern_for_belt_type_vertical(component) {
130
+ var { width } = component.bounds;
131
+ var { rollWidth = 10 } = component.model;
132
+ var rw = Math.max(rollWidth, 1);
133
+ var color = FILL_STYLES[component.value] || FILL_STYLES[0];
134
+ var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0];
135
+ if (!component._roller_pattern_v)
136
+ component._roller_pattern_v = document.createElement('canvas');
137
+ component._roller_pattern_v.width = width;
138
+ component._roller_pattern_v.height = rw;
139
+ var ctx = component._roller_pattern_v.getContext('2d');
140
+ ctx.beginPath();
141
+ ctx.fillStyle = color;
142
+ ctx.strokeStyle = stroke;
143
+ ctx.lineWidth = 1;
144
+ ctx.rect(0, 0, width, rw);
145
+ ctx.fill();
146
+ ctx.globalAlpha = 0.2;
147
+ var y_for_belt = (component._step || 0) % rw;
148
+ if (component.value == 2)
149
+ y_for_belt = rw - y_for_belt;
150
+ ctx.beginPath();
151
+ ctx.moveTo(0, y_for_belt);
152
+ ctx.lineTo(width, y_for_belt);
153
+ ctx.stroke();
154
+ return component._roller_pattern_v;
155
+ }
83
156
  const patterns = [pattern_for_roller_type, pattern_for_belt_type];
157
+ const patternsVertical = [pattern_for_roller_type_vertical, pattern_for_belt_type_vertical];
84
158
  export default (superclass) => {
85
159
  var A = class extends ValueHolder(superclass) {
86
160
  dispose() {
87
161
  super.dispose();
88
162
  delete this._roller_pattern;
163
+ delete this._roller_pattern_v;
89
164
  }
90
165
  animOnState() {
91
166
  if ((this.value !== 1 && this.value !== 2) || this.disposed)
@@ -106,8 +181,12 @@ export default (superclass) => {
106
181
  return conveyorType;
107
182
  }
108
183
  get fillStyle() {
184
+ const vertical = isVerticalOrientation(this);
185
+ const patternCanvas = vertical
186
+ ? patternsVertical[this.conveyorType](this)
187
+ : patterns[this.conveyorType](this);
109
188
  return {
110
- image: patterns[this.conveyorType](this),
189
+ image: patternCanvas,
111
190
  offsetX: 0,
112
191
  offsetY: 0,
113
192
  type: 'pattern'
@@ -1 +1 @@
1
- {"version":3,"file":"mixin-conveyor.js","sourceRoot":"","sources":["../src/mixin-conveyor.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Class, Component, ValueHolder } from '@hatiolab/things-scene'\n\nconst TYPE_ROLLER = 0\nconst TYPE_BELT = 1\n\nconst FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b'] // IDLE, RUN, RUN(REVERSE), WARN, ERROR\nconst STROKE_STYLES = ['#999', '#87b1db', '#87b1db', '#d96f21', '#a73928'] // IDLE, RUN, RUN(REVERSE), WARN, ERROR\n\ntype RollerPattern = {\n width: number\n height: number\n}\n\nfunction pattern_for_belt_type(component: any) {\n var { height } = component.bounds\n\n var { rollWidth = 10 } = component.model\n\n var width = Math.max(rollWidth, 1)\n\n var color = FILL_STYLES[component.value] || FILL_STYLES[0]\n var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0]\n var lineWidth = 1\n\n if (!component._roller_pattern) component._roller_pattern = document.createElement('canvas')\n\n component._roller_pattern.width = width\n component._roller_pattern.height = height\n\n var context = component._roller_pattern.getContext('2d')\n\n context.beginPath()\n context.fillStyle = color\n context.strokeStyle = stroke\n context.lineWidth = lineWidth\n\n context.moveTo(0, 0)\n context.lineTo(width, 0)\n context.lineTo(width, height)\n context.lineTo(0, height)\n context.lineTo(0, 0)\n context.fill()\n\n context.beginPath()\n\n context.globalAlpha = 0.2\n\n var x_for_belt = (component._step || 0) % width\n if (component.value == 2) x_for_belt = width - x_for_belt\n\n context.moveTo(x_for_belt, height)\n context.lineTo(x_for_belt, 0)\n\n context.stroke()\n\n return component._roller_pattern\n}\n\nfunction pattern_for_roller_type(component: any) {\n var { height } = component.bounds\n\n var { rollWidth = 10, animated } = component.model\n\n // var modelWidth = component.model.width;\n\n var width = Math.max(rollWidth, 1)\n\n var color = FILL_STYLES[component.value] || FILL_STYLES[0]\n var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0]\n var lineWidth = Math.min(1, width / 10)\n\n width += lineWidth * 2\n\n if (!component._roller_pattern) component._roller_pattern = document.createElement('canvas')\n\n var gap = Math.floor((width * 2) / 3)\n\n // while (Math.round(modelWidth - width) % (width + gap) > gap) {\n // gap++\n // console.log(gap, Math.round(modelWidth - width) % (width + gap))\n // }\n\n component._roller_pattern.width = width + gap\n component._roller_pattern.height = height\n\n var context = component._roller_pattern.getContext('2d')\n\n context.beginPath()\n context.fillStyle = color\n context.strokeStyle = stroke\n context.lineWidth = lineWidth\n\n context.ellipse(lineWidth + width / 2, height - width / 4 - lineWidth, width / 2, width / 4, 0, 0, Math.PI)\n\n context.moveTo(lineWidth, height - width / 4)\n context.lineTo(lineWidth, width / 4)\n\n context.ellipse(lineWidth + width / 2, width / 4 + lineWidth, width / 2, width / 4, 0, Math.PI, 0)\n\n context.lineTo(lineWidth + width, height - width / 4)\n\n context.fill()\n context.stroke()\n\n context.globalAlpha = 0.2\n\n context.lineWidth = width / 3\n\n if (animated) {\n var x_for_roll = component._step % width\n if (component.value == 2) x_for_roll = width - x_for_roll\n\n context.moveTo(x_for_roll, height - width / 4)\n context.lineTo(x_for_roll, width / 4)\n\n context.stroke()\n }\n\n return component._roller_pattern\n}\n\nconst patterns = [pattern_for_roller_type, pattern_for_belt_type]\n\nexport default (superclass: Class) => {\n var A = class extends ValueHolder(superclass) {\n dispose() {\n super.dispose()\n delete this._roller_pattern\n }\n\n animOnState() {\n if ((this.value !== 1 && this.value !== 2) || this.disposed) return\n\n if (!this._step || this._step > 40000) this._step = 0\n\n this._step++\n\n var self = this\n\n requestAnimationFrame(function () {\n self.clearCache('fillStyle')\n self.invalidate()\n })\n }\n\n get conveyorType() {\n var conveyorType = this.getState('conveyorType')\n if (conveyorType != TYPE_BELT && conveyorType != TYPE_ROLLER) conveyorType = TYPE_ROLLER\n return conveyorType\n }\n\n get fillStyle() {\n return {\n image: patterns[this.conveyorType](this),\n offsetX: 0,\n offsetY: 0,\n type: 'pattern'\n }\n }\n }\n\n Component.memoize(A.prototype, 'fillStyle', false)\n Component.memoize(A.prototype, 'conveyorType', false)\n\n return A\n}\n"]}
1
+ {"version":3,"file":"mixin-conveyor.js","sourceRoot":"","sources":["../src/mixin-conveyor.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Class, Component, ValueHolder } from '@hatiolab/things-scene'\n\nconst TYPE_ROLLER = 0\nconst TYPE_BELT = 1\n\nconst FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b'] // IDLE, RUN, RUN(REVERSE), WARN, ERROR\nconst STROKE_STYLES = ['#999', '#87b1db', '#87b1db', '#d96f21', '#a73928'] // IDLE, RUN, RUN(REVERSE), WARN, ERROR\n\ntype RollerPattern = {\n width: number\n height: number\n}\n\nfunction pattern_for_belt_type(component: any) {\n var { height } = component.bounds\n\n var { rollWidth = 10 } = component.model\n\n var width = Math.max(rollWidth, 1)\n\n var color = FILL_STYLES[component.value] || FILL_STYLES[0]\n var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0]\n var lineWidth = 1\n\n if (!component._roller_pattern) component._roller_pattern = document.createElement('canvas')\n\n component._roller_pattern.width = width\n component._roller_pattern.height = height\n\n var context = component._roller_pattern.getContext('2d')\n\n context.beginPath()\n context.fillStyle = color\n context.strokeStyle = stroke\n context.lineWidth = lineWidth\n\n context.moveTo(0, 0)\n context.lineTo(width, 0)\n context.lineTo(width, height)\n context.lineTo(0, height)\n context.lineTo(0, 0)\n context.fill()\n\n context.beginPath()\n\n context.globalAlpha = 0.2\n\n var x_for_belt = (component._step || 0) % width\n if (component.value == 2) x_for_belt = width - x_for_belt\n\n context.moveTo(x_for_belt, height)\n context.lineTo(x_for_belt, 0)\n\n context.stroke()\n\n return component._roller_pattern\n}\n\nfunction isVerticalOrientation(component: any): boolean {\n const { orientation } = component.model || {}\n const { width, height } = component.bounds\n return orientation === 'vertical' ? true\n : orientation === 'horizontal' ? false\n : width < height\n}\n\nfunction pattern_for_roller_type(component: any) {\n var { height } = component.bounds\n\n var { rollWidth = 10, animated } = component.model\n\n // var modelWidth = component.model.width;\n\n var width = Math.max(rollWidth, 1)\n\n var color = FILL_STYLES[component.value] || FILL_STYLES[0]\n var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0]\n var lineWidth = Math.min(1, width / 10)\n\n width += lineWidth * 2\n\n if (!component._roller_pattern) component._roller_pattern = document.createElement('canvas')\n\n var gap = Math.floor((width * 2) / 3)\n\n // while (Math.round(modelWidth - width) % (width + gap) > gap) {\n // gap++\n // console.log(gap, Math.round(modelWidth - width) % (width + gap))\n // }\n\n component._roller_pattern.width = width + gap\n component._roller_pattern.height = height\n\n var context = component._roller_pattern.getContext('2d')\n\n context.beginPath()\n context.fillStyle = color\n context.strokeStyle = stroke\n context.lineWidth = lineWidth\n\n context.ellipse(lineWidth + width / 2, height - width / 4 - lineWidth, width / 2, width / 4, 0, 0, Math.PI)\n\n context.moveTo(lineWidth, height - width / 4)\n context.lineTo(lineWidth, width / 4)\n\n context.ellipse(lineWidth + width / 2, width / 4 + lineWidth, width / 2, width / 4, 0, Math.PI, 0)\n\n context.lineTo(lineWidth + width, height - width / 4)\n\n context.fill()\n context.stroke()\n\n context.globalAlpha = 0.2\n\n context.lineWidth = width / 3\n\n if (animated) {\n var x_for_roll = component._step % width\n if (component.value == 2) x_for_roll = width - x_for_roll\n\n context.moveTo(x_for_roll, height - width / 4)\n context.lineTo(x_for_roll, width / 4)\n\n context.stroke()\n }\n\n return component._roller_pattern\n}\n\nfunction pattern_for_roller_type_vertical(component: any) {\n var { width } = component.bounds\n var { rollWidth = 10, animated } = component.model\n\n var rw = Math.max(rollWidth, 1)\n var color = FILL_STYLES[component.value] || FILL_STYLES[0]\n var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0]\n var lineWidth = Math.min(1, rw / 10)\n rw += lineWidth * 2\n var gap = Math.floor((rw * 2) / 3)\n\n if (!component._roller_pattern_v) component._roller_pattern_v = document.createElement('canvas')\n\n component._roller_pattern_v.width = width\n component._roller_pattern_v.height = rw + gap\n\n var ctx = component._roller_pattern_v.getContext('2d')\n\n ctx.beginPath()\n ctx.fillStyle = color\n ctx.strokeStyle = stroke\n ctx.lineWidth = lineWidth\n\n // 가로 롤러: 좌측 반타원 + 본체 + 우측 반타원\n var cy = lineWidth + rw / 2\n ctx.ellipse(rw / 4 + lineWidth, cy, rw / 4, rw / 2, 0, Math.PI / 2, -Math.PI / 2, true)\n ctx.lineTo(width - rw / 4 - lineWidth, lineWidth)\n ctx.ellipse(width - rw / 4 - lineWidth, cy, rw / 4, rw / 2, 0, -Math.PI / 2, Math.PI / 2, true)\n ctx.lineTo(rw / 4 + lineWidth, lineWidth + rw)\n\n ctx.fill()\n ctx.stroke()\n\n if (animated) {\n ctx.globalAlpha = 0.2\n ctx.lineWidth = rw / 3\n var y_for_roll = (component._step || 0) % rw\n if (component.value == 2) y_for_roll = rw - y_for_roll\n ctx.beginPath()\n ctx.moveTo(rw / 4, cy - rw / 2 + y_for_roll)\n ctx.lineTo(width - rw / 4, cy - rw / 2 + y_for_roll)\n ctx.stroke()\n }\n\n return component._roller_pattern_v\n}\n\nfunction pattern_for_belt_type_vertical(component: any) {\n var { width } = component.bounds\n var { rollWidth = 10 } = component.model\n\n var rw = Math.max(rollWidth, 1)\n var color = FILL_STYLES[component.value] || FILL_STYLES[0]\n var stroke = STROKE_STYLES[component.value] || STROKE_STYLES[0]\n\n if (!component._roller_pattern_v) component._roller_pattern_v = document.createElement('canvas')\n\n component._roller_pattern_v.width = width\n component._roller_pattern_v.height = rw\n\n var ctx = component._roller_pattern_v.getContext('2d')\n\n ctx.beginPath()\n ctx.fillStyle = color\n ctx.strokeStyle = stroke\n ctx.lineWidth = 1\n\n ctx.rect(0, 0, width, rw)\n ctx.fill()\n\n ctx.globalAlpha = 0.2\n var y_for_belt = (component._step || 0) % rw\n if (component.value == 2) y_for_belt = rw - y_for_belt\n ctx.beginPath()\n ctx.moveTo(0, y_for_belt)\n ctx.lineTo(width, y_for_belt)\n ctx.stroke()\n\n return component._roller_pattern_v\n}\n\nconst patterns = [pattern_for_roller_type, pattern_for_belt_type]\nconst patternsVertical = [pattern_for_roller_type_vertical, pattern_for_belt_type_vertical]\n\nexport default (superclass: Class) => {\n var A = class extends ValueHolder(superclass) {\n dispose() {\n super.dispose()\n delete this._roller_pattern\n delete this._roller_pattern_v\n }\n\n animOnState() {\n if ((this.value !== 1 && this.value !== 2) || this.disposed) return\n\n if (!this._step || this._step > 40000) this._step = 0\n\n this._step++\n\n var self = this\n\n requestAnimationFrame(function () {\n self.clearCache('fillStyle')\n self.invalidate()\n })\n }\n\n get conveyorType() {\n var conveyorType = this.getState('conveyorType')\n if (conveyorType != TYPE_BELT && conveyorType != TYPE_ROLLER) conveyorType = TYPE_ROLLER\n return conveyorType\n }\n\n get fillStyle() {\n const vertical = isVerticalOrientation(this)\n const patternCanvas = vertical\n ? patternsVertical[this.conveyorType](this)\n : patterns[this.conveyorType](this)\n\n return {\n image: patternCanvas,\n offsetX: 0,\n offsetY: 0,\n type: 'pattern'\n }\n }\n }\n\n Component.memoize(A.prototype, 'fillStyle', false)\n Component.memoize(A.prototype, 'conveyorType', false)\n\n return A\n}\n"]}
package/dist/scanner.d.ts CHANGED
@@ -4,8 +4,8 @@ interface ScannerMixin {
4
4
  declare const MixinShape: typeof Component & (new (...args: any[]) => ScannerMixin);
5
5
  export default class Scanner extends MixinShape {
6
6
  get nature(): ComponentNature;
7
+ get anchors(): never[];
7
8
  render(ctx: CanvasRenderingContext2D): void;
8
- is3dish(): boolean;
9
9
  buildRealObject(): RealObject | undefined;
10
10
  }
11
11
  export {};
package/dist/scanner.js CHANGED
@@ -32,6 +32,9 @@ let Scanner = class Scanner extends MixinShape {
32
32
  get nature() {
33
33
  return NATURE;
34
34
  }
35
+ get anchors() {
36
+ return [];
37
+ }
35
38
  render(ctx) {
36
39
  var { width, height, left, top } = this.state;
37
40
  var radius = width / 10;
@@ -47,9 +50,6 @@ let Scanner = class Scanner extends MixinShape {
47
50
  ctx.quadraticCurveTo(left, top, left + radius, top);
48
51
  ctx.clip();
49
52
  }
50
- is3dish() {
51
- return true;
52
- }
53
53
  buildRealObject() {
54
54
  return new Scanner3D(this);
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAO3C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;CACF,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAEpB,sBAAsB;AACtB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAyE,CAAA;AAGzG,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAC7C,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7C,IAAI,MAAM,GAAG,KAAK,GAAG,EAAE,CAAA;QAEvB,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QAC9B,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACtC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACnE,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QAC/C,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACrF,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACvC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QACrE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QAC9B,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACnD,GAAG,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,SAAS,CAAC,IAAW,CAAC,CAAA;IACnC,CAAC;CACF,CAAA;AA9BoB,OAAO;IAD3B,cAAc,CAAC,SAAS,CAAC;GACL,OAAO,CA8B3B;eA9BoB,OAAO","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, sceneComponent, Shape } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinScanner from './mixin-scanner.js'\nimport { Scanner3D } from './scanner-3d.js'\n\n// MixinScanner에서 확장된 클래스의 인터페이스 정의\ninterface ScannerMixin {\n // 필요한 메서드나 속성을 여기에 정의\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ]\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 2\nconst STAT_ERROR = 3\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinScanner(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => ScannerMixin)\n\n@sceneComponent('scanner')\nexport default class Scanner extends MixinShape {\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top } = this.state\n\n var radius = width / 10\n\n ctx.beginPath()\n ctx.moveTo(left + radius, top)\n ctx.lineTo(left + width - radius, top)\n ctx.quadraticCurveTo(left + width, top, left + width, top + radius)\n ctx.lineTo(left + width, top + height - radius)\n ctx.quadraticCurveTo(left + width, top + height, left + width - radius, top + height)\n ctx.lineTo(left + radius, top + height)\n ctx.quadraticCurveTo(left, top + height, left, top + height - radius)\n ctx.lineTo(left, top + radius)\n ctx.quadraticCurveTo(left, top, left + radius, top)\n ctx.clip()\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Scanner3D(this as any)\n }\n}\n"]}
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAO3C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;CACF,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAEpB,sBAAsB;AACtB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAyE,CAAA;AAGzG,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAC7C,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7C,IAAI,MAAM,GAAG,KAAK,GAAG,EAAE,CAAA;QAEvB,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QAC9B,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACtC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACnE,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QAC/C,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACrF,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACvC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QACrE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QAC9B,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACnD,GAAG,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IACD,eAAe;QACb,OAAO,IAAI,SAAS,CAAC,IAAW,CAAC,CAAA;IACnC,CAAC;CACF,CAAA;AA7BoB,OAAO;IAD3B,cAAc,CAAC,SAAS,CAAC;GACL,OAAO,CA6B3B;eA7BoB,OAAO","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, sceneComponent, Shape } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinScanner from './mixin-scanner.js'\nimport { Scanner3D } from './scanner-3d.js'\n\n// MixinScanner에서 확장된 클래스의 인터페이스 정의\ninterface ScannerMixin {\n // 필요한 메서드나 속성을 여기에 정의\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ]\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 2\nconst STAT_ERROR = 3\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinScanner(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => ScannerMixin)\n\n@sceneComponent('scanner')\nexport default class Scanner extends MixinShape {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top } = this.state\n\n var radius = width / 10\n\n ctx.beginPath()\n ctx.moveTo(left + radius, top)\n ctx.lineTo(left + width - radius, top)\n ctx.quadraticCurveTo(left + width, top, left + width, top + radius)\n ctx.lineTo(left + width, top + height - radius)\n ctx.quadraticCurveTo(left + width, top + height, left + width - radius, top + height)\n ctx.lineTo(left + radius, top + height)\n ctx.quadraticCurveTo(left, top + height, left, top + height - radius)\n ctx.lineTo(left, top + radius)\n ctx.quadraticCurveTo(left, top, left + radius, top)\n ctx.clip()\n }\n buildRealObject(): RealObject | undefined {\n return new Scanner3D(this as any)\n }\n}\n"]}
@@ -9,9 +9,9 @@ interface WheelSorterMixin {
9
9
  declare const MixinShape: typeof Component & (new (...args: any[]) => WheelSorterMixin);
10
10
  export default class WheelSorter extends MixinShape {
11
11
  get nature(): ComponentNature;
12
+ get anchors(): never[];
12
13
  render(ctx: CanvasRenderingContext2D): void;
13
14
  postrender(ctx: CanvasRenderingContext2D): void;
14
- is3dish(): boolean;
15
15
  buildRealObject(): RealObject | undefined;
16
16
  }
17
17
  export {};
@@ -44,6 +44,9 @@ let WheelSorter = class WheelSorter extends MixinShape {
44
44
  get nature() {
45
45
  return NATURE;
46
46
  }
47
+ get anchors() {
48
+ return [];
49
+ }
47
50
  render(ctx) {
48
51
  var { width, height, left, top, animated } = this.state;
49
52
  animated && this.animOnState();
@@ -55,9 +58,6 @@ let WheelSorter = class WheelSorter extends MixinShape {
55
58
  super.postrender(ctx);
56
59
  this._draw_pattern(ctx);
57
60
  }
58
- is3dish() {
59
- return true;
60
- }
61
61
  buildRealObject() {
62
62
  return new WheelSorter3D(this);
63
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wheel-sorter.js","sourceRoot":"","sources":["../src/wheel-sorter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,gBAAgB,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAWpD,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,8BAA8B;CACrC,CAAA;AAED,sBAAsB;AACtB,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,CACP,CAAA;AAG7B,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IACjD,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAEvD,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAE9B,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAElC,GAAG,CAAC,IAAI,EAAE,CAAA,CAAC,8BAA8B;IAC3C,CAAC;IAED,UAAU,CAAC,GAA6B;QACtC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,aAAa,CAAC,IAAW,CAAC,CAAA;IACvC,CAAC;CACF,CAAA;AA5BoB,WAAW;IAD/B,cAAc,CAAC,cAAc,CAAC;GACV,WAAW,CA4B/B;eA5BoB,WAAW","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinWheelSorter from './mixin-wheel-sorter.js'\nimport { WheelSorter3D } from './wheel-sorter-3d.js'\n\n// MixinWheelSorter에서 확장된 클래스의 인터페이스 정의\ninterface WheelSorterMixin {\n animOnState(): void\n _draw_pattern(ctx: CanvasRenderingContext2D): void\n _draw_circle(ctx: CanvasRenderingContext2D): void\n _draw_inner(ctx: CanvasRenderingContext2D): void\n _draw_wheel(ctx: CanvasRenderingContext2D): void\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'tilt',\n name: 'tilt'\n },\n {\n type: 'number',\n label: 'wheel-size',\n name: 'wheelSize'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/wheel-sorter'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinWheelSorter(RectPath(Shape)) as unknown as typeof Component &\n (new (...args: any[]) => WheelSorterMixin)\n\n@sceneComponent('wheel-sorter')\nexport default class WheelSorter extends MixinShape {\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n\n ctx.clip() // bound를 벗어난 영역에도 그려지는 것을 예방.\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n this._draw_pattern(ctx)\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new WheelSorter3D(this as any)\n }\n}\n"]}
1
+ {"version":3,"file":"wheel-sorter.js","sourceRoot":"","sources":["../src/wheel-sorter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,gBAAgB,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAWpD,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,8BAA8B;CACrC,CAAA;AAED,sBAAsB;AACtB,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,CACP,CAAA;AAG7B,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IACjD,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAEvD,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAE9B,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAElC,GAAG,CAAC,IAAI,EAAE,CAAA,CAAC,8BAA8B;IAC3C,CAAC;IAED,UAAU,CAAC,GAA6B;QACtC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IACD,eAAe;QACb,OAAO,IAAI,aAAa,CAAC,IAAW,CAAC,CAAA;IACvC,CAAC;CACF,CAAA;AA3BoB,WAAW;IAD/B,cAAc,CAAC,cAAc,CAAC;GACV,WAAW,CA2B/B;eA3BoB,WAAW","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinWheelSorter from './mixin-wheel-sorter.js'\nimport { WheelSorter3D } from './wheel-sorter-3d.js'\n\n// MixinWheelSorter에서 확장된 클래스의 인터페이스 정의\ninterface WheelSorterMixin {\n animOnState(): void\n _draw_pattern(ctx: CanvasRenderingContext2D): void\n _draw_circle(ctx: CanvasRenderingContext2D): void\n _draw_inner(ctx: CanvasRenderingContext2D): void\n _draw_wheel(ctx: CanvasRenderingContext2D): void\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'tilt',\n name: 'tilt'\n },\n {\n type: 'number',\n label: 'wheel-size',\n name: 'wheelSize'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/wheel-sorter'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinWheelSorter(RectPath(Shape)) as unknown as typeof Component &\n (new (...args: any[]) => WheelSorterMixin)\n\n@sceneComponent('wheel-sorter')\nexport default class WheelSorter extends MixinShape {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n\n ctx.clip() // bound를 벗어난 영역에도 그려지는 것을 예방.\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n this._draw_pattern(ctx)\n }\n buildRealObject(): RealObject | undefined {\n return new WheelSorter3D(this as any)\n }\n}\n"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/scene-wheel-sorter",
3
3
  "description": "The wheel sorter component for things-scene",
4
4
  "author": "heartyoh",
5
- "version": "10.0.0-beta.12",
5
+ "version": "10.0.0-beta.14",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
@@ -60,5 +60,5 @@
60
60
  "prettier --write"
61
61
  ]
62
62
  },
63
- "gitHead": "b8d77737806b19ed48fef2de4f07b6913b978cb5"
63
+ "gitHead": "3defb7207c541d87da3f5ebdd34f06d2e9e1cebb"
64
64
  }