@operato/scene-visualizer 9.1.1 → 10.0.0-beta.1

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.
Files changed (181) hide show
  1. package/dist/banner.d.ts +232 -3
  2. package/dist/banner.js +1 -2
  3. package/dist/banner.js.map +1 -1
  4. package/dist/camera.d.ts +232 -3
  5. package/dist/camera.js +1 -2
  6. package/dist/camera.js.map +1 -1
  7. package/dist/carrier.d.ts +263 -0
  8. package/dist/carrier.js +272 -0
  9. package/dist/carrier.js.map +1 -0
  10. package/dist/cube.d.ts +232 -4
  11. package/dist/cube.js +1 -2
  12. package/dist/cube.js.map +1 -1
  13. package/dist/cylinder.d.ts +1 -3
  14. package/dist/cylinder.js +1 -2
  15. package/dist/cylinder.js.map +1 -1
  16. package/dist/desk.d.ts +238 -3
  17. package/dist/desk.js +1 -2
  18. package/dist/desk.js.map +1 -1
  19. package/dist/editors/index.d.ts +1 -0
  20. package/dist/editors/index.js +5 -0
  21. package/dist/editors/index.js.map +1 -1
  22. package/dist/editors/property-editor-gltf-fill-targets.d.ts +17 -0
  23. package/dist/editors/property-editor-gltf-fill-targets.js +211 -0
  24. package/dist/editors/property-editor-gltf-fill-targets.js.map +1 -0
  25. package/dist/editors/property-editor-gltf-info.js +38 -29
  26. package/dist/editors/property-editor-gltf-info.js.map +1 -1
  27. package/dist/editors/property-editor-location-increase-pattern.js +91 -95
  28. package/dist/editors/property-editor-location-increase-pattern.js.map +1 -1
  29. package/dist/effects/outline.js +1 -1
  30. package/dist/effects/outline.js.map +1 -1
  31. package/dist/ellipse.js +2 -4
  32. package/dist/ellipse.js.map +1 -1
  33. package/dist/gltf-object.d.ts +232 -3
  34. package/dist/gltf-object.js +1 -2
  35. package/dist/gltf-object.js.map +1 -1
  36. package/dist/html-overlay-element.js +3 -7
  37. package/dist/html-overlay-element.js.map +1 -1
  38. package/dist/index.d.ts +5 -17
  39. package/dist/index.js +7 -17
  40. package/dist/index.js.map +1 -1
  41. package/dist/light.d.ts +1 -2
  42. package/dist/light.js +1 -2
  43. package/dist/light.js.map +1 -1
  44. package/dist/polygon.js +2 -4
  45. package/dist/polygon.js.map +1 -1
  46. package/dist/rack-table-3d.d.ts +16 -0
  47. package/dist/rack-table-3d.js +94 -0
  48. package/dist/rack-table-3d.js.map +1 -0
  49. package/dist/rack-table-cell.d.ts +238 -3
  50. package/dist/rack-table-cell.js +44 -51
  51. package/dist/rack-table-cell.js.map +1 -1
  52. package/dist/rack-table-location.d.ts +37 -0
  53. package/dist/rack-table-location.js +227 -0
  54. package/dist/rack-table-location.js.map +1 -0
  55. package/dist/rack-table.d.ts +13 -29
  56. package/dist/rack-table.js +108 -380
  57. package/dist/rack-table.js.map +1 -1
  58. package/dist/rack.d.ts +3 -5
  59. package/dist/rack.js +7 -9
  60. package/dist/rack.js.map +1 -1
  61. package/dist/rect.js +2 -4
  62. package/dist/rect.js.map +1 -1
  63. package/dist/signal-tower.d.ts +492 -0
  64. package/dist/signal-tower.js +275 -0
  65. package/dist/signal-tower.js.map +1 -0
  66. package/dist/sphere.d.ts +1 -3
  67. package/dist/sphere.js +1 -2
  68. package/dist/sphere.js.map +1 -1
  69. package/dist/sprite.d.ts +232 -3
  70. package/dist/sprite.js +1 -2
  71. package/dist/sprite.js.map +1 -1
  72. package/dist/stock.d.ts +22 -10
  73. package/dist/stock.js +130 -109
  74. package/dist/stock.js.map +1 -1
  75. package/dist/tank.d.ts +492 -0
  76. package/dist/tank.js +312 -0
  77. package/dist/tank.js.map +1 -0
  78. package/dist/templates/carrier.d.ts +19 -0
  79. package/dist/templates/carrier.js +20 -0
  80. package/dist/templates/carrier.js.map +1 -0
  81. package/dist/templates/cube.js +1 -1
  82. package/dist/templates/cube.js.map +1 -1
  83. package/dist/templates/cylinder.js +3 -3
  84. package/dist/templates/cylinder.js.map +1 -1
  85. package/dist/templates/index.d.ts +1 -0
  86. package/dist/templates/index.js +9 -1
  87. package/dist/templates/index.js.map +1 -1
  88. package/dist/templates/signal-tower.d.ts +21 -0
  89. package/dist/templates/signal-tower.js +22 -0
  90. package/dist/templates/signal-tower.js.map +1 -0
  91. package/dist/templates/sphere.d.ts +1 -0
  92. package/dist/templates/sphere.js +5 -4
  93. package/dist/templates/sphere.js.map +1 -1
  94. package/dist/templates/tank.d.ts +21 -0
  95. package/dist/templates/tank.js +22 -0
  96. package/dist/templates/tank.js.map +1 -0
  97. package/dist/templates/vehicle.d.ts +19 -0
  98. package/dist/templates/vehicle.js +20 -0
  99. package/dist/templates/vehicle.js.map +1 -0
  100. package/dist/text.js +2 -4
  101. package/dist/text.js.map +1 -1
  102. package/dist/three-container.d.ts +11 -35
  103. package/dist/three-container.js +128 -322
  104. package/dist/three-container.js.map +1 -1
  105. package/dist/three-controls.d.ts +101 -1
  106. package/dist/three-controls.js +339 -541
  107. package/dist/three-controls.js.map +1 -1
  108. package/dist/three-space.d.ts +6 -83
  109. package/dist/three-space.js +25 -537
  110. package/dist/three-space.js.map +1 -1
  111. package/dist/threed/index.d.ts +1 -0
  112. package/dist/threed/index.js +1 -0
  113. package/dist/threed/index.js.map +1 -1
  114. package/dist/threed/interfaces.d.ts +15 -0
  115. package/dist/threed/interfaces.js +5 -0
  116. package/dist/threed/interfaces.js.map +1 -0
  117. package/dist/threed/managers/camera-manager.d.ts +14 -0
  118. package/dist/threed/managers/camera-manager.js +60 -0
  119. package/dist/threed/managers/camera-manager.js.map +1 -0
  120. package/dist/threed/managers/controls-manager.d.ts +50 -0
  121. package/dist/threed/managers/controls-manager.js +249 -0
  122. package/dist/threed/managers/controls-manager.js.map +1 -0
  123. package/dist/threed/managers/event-manager3d.d.ts +19 -0
  124. package/dist/threed/managers/event-manager3d.js +76 -0
  125. package/dist/threed/managers/event-manager3d.js.map +1 -0
  126. package/dist/threed/managers/index.d.ts +7 -0
  127. package/dist/threed/managers/index.js +7 -0
  128. package/dist/threed/managers/index.js.map +1 -0
  129. package/dist/threed/managers/light-manager.d.ts +7 -0
  130. package/dist/threed/managers/light-manager.js +37 -0
  131. package/dist/threed/managers/light-manager.js.map +1 -0
  132. package/dist/threed/managers/renderer-manager.d.ts +30 -0
  133. package/dist/threed/managers/renderer-manager.js +120 -0
  134. package/dist/threed/managers/renderer-manager.js.map +1 -0
  135. package/dist/threed/managers/scene-manager.d.ts +15 -0
  136. package/dist/threed/managers/scene-manager.js +48 -0
  137. package/dist/threed/managers/scene-manager.js.map +1 -0
  138. package/dist/threed/managers/types.d.ts +36 -0
  139. package/dist/threed/managers/types.js +2 -0
  140. package/dist/threed/managers/types.js.map +1 -0
  141. package/dist/threed/real-object-dom-element.js +11 -3
  142. package/dist/threed/real-object-dom-element.js.map +1 -1
  143. package/dist/threed/real-object-extrude.d.ts +1 -0
  144. package/dist/threed/real-object-extrude.js +7 -0
  145. package/dist/threed/real-object-extrude.js.map +1 -1
  146. package/dist/threed/real-object-gltf.js +6 -2
  147. package/dist/threed/real-object-gltf.js.map +1 -1
  148. package/dist/threed/real-object-mesh.js +4 -6
  149. package/dist/threed/real-object-mesh.js.map +1 -1
  150. package/dist/threed/real-object-registry.d.ts +7 -0
  151. package/dist/threed/real-object-registry.js +32 -0
  152. package/dist/threed/real-object-registry.js.map +1 -0
  153. package/dist/threed/real-object-scene.js +10 -5
  154. package/dist/threed/real-object-scene.js.map +1 -1
  155. package/dist/threed/real-object-sprite-2d.js.map +1 -1
  156. package/dist/threed/real-object-sprite.js +2 -0
  157. package/dist/threed/real-object-sprite.js.map +1 -1
  158. package/dist/threed/real-object-text.js +2 -0
  159. package/dist/threed/real-object-text.js.map +1 -1
  160. package/dist/threed/real-object.d.ts +3 -2
  161. package/dist/threed/real-object.js +7 -16
  162. package/dist/threed/real-object.js.map +1 -1
  163. package/dist/threed/three-dimensional-container.d.ts +1 -2
  164. package/dist/threed/three-dimensional-container.js.map +1 -1
  165. package/dist/threed/utils/dispose.d.ts +2 -0
  166. package/dist/threed/utils/dispose.js +32 -0
  167. package/dist/threed/utils/dispose.js.map +1 -0
  168. package/dist/vehicle.d.ts +248 -0
  169. package/dist/vehicle.js +133 -0
  170. package/dist/vehicle.js.map +1 -0
  171. package/dist/visualizer.d.ts +4 -5
  172. package/dist/visualizer.js +15 -28
  173. package/dist/visualizer.js.map +1 -1
  174. package/dist/wall.d.ts +232 -4
  175. package/dist/wall.js +1 -2
  176. package/dist/wall.js.map +1 -1
  177. package/icons/carrier.png +0 -0
  178. package/icons/signal-tower.png +0 -0
  179. package/icons/tank.png +0 -0
  180. package/icons/vehicle.png +0 -0
  181. package/package.json +16 -18
@@ -0,0 +1,275 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+ import { __decorate } from "tslib";
5
+ import { RealObjectGroup, RectPath, Shape, ValueHolder, sceneComponent } from '@hatiolab/things-scene';
6
+ import * as THREE from 'three';
7
+ import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js';
8
+ const NATURE = {
9
+ mutable: false,
10
+ resizable: true,
11
+ rotatable: true,
12
+ properties: [
13
+ {
14
+ type: 'number',
15
+ label: 'value',
16
+ name: 'value',
17
+ property: 'value'
18
+ },
19
+ {
20
+ type: 'checkbox',
21
+ label: 'blink',
22
+ name: 'blink',
23
+ property: 'blink'
24
+ }
25
+ ],
26
+ help: 'scene/component/signal-tower'
27
+ };
28
+ /* ── 색상 상수 ── */
29
+ const LIGHT_COLORS = {
30
+ red: { on: '#cc0000', off: '#1a0505' },
31
+ yellow: { on: '#cc8800', off: '#1a1400' },
32
+ green: { on: '#00bb00', off: '#051a05' }
33
+ };
34
+ const BODY_COLOR = '#333333';
35
+ const POLE_COLOR = '#888888';
36
+ const RING_COLOR = '#222222';
37
+ /* ── 2D 렌더 ── */
38
+ const BLINK_PERIOD = 500; // ms
39
+ function isBlinkOn() {
40
+ return Math.floor(Date.now() / BLINK_PERIOD) % 2 === 0;
41
+ }
42
+ function renderSignalTower(ctx, x, y, w, h, value, blink) {
43
+ const sep = Math.max(1, h * 0.01);
44
+ const poleH = h * 0.08;
45
+ const lightH = (h - sep * 2 - poleH) / 3;
46
+ const blinkVisible = !blink || isBlinkOn();
47
+ const lights = [
48
+ { color: LIGHT_COLORS.red, on: !!(value & 4) && blinkVisible },
49
+ { color: LIGHT_COLORS.yellow, on: !!(value & 2) && blinkVisible },
50
+ { color: LIGHT_COLORS.green, on: !!(value & 1) && blinkVisible }
51
+ ];
52
+ let cy = y;
53
+ for (let i = 0; i < 3; i++) {
54
+ const light = lights[i];
55
+ // light band — full width
56
+ ctx.fillStyle = light.on ? light.color.on : light.color.off;
57
+ ctx.fillRect(x, cy, w, lightH);
58
+ // ON glow overlay
59
+ if (light.on) {
60
+ const cx = x + w / 2;
61
+ const my = cy + lightH / 2;
62
+ const grad = ctx.createRadialGradient(cx, my, 0, cx, my, w * 0.6);
63
+ grad.addColorStop(0, '#ffffff88');
64
+ grad.addColorStop(1, '#ffffff00');
65
+ ctx.fillStyle = grad;
66
+ ctx.fillRect(x, cy, w, lightH);
67
+ }
68
+ cy += lightH;
69
+ // thin separator between lights
70
+ if (i < 2) {
71
+ ctx.fillStyle = RING_COLOR;
72
+ ctx.fillRect(x, cy, w, sep);
73
+ cy += sep;
74
+ }
75
+ }
76
+ // pole stub
77
+ const poleW = w * 0.3;
78
+ ctx.fillStyle = POLE_COLOR;
79
+ ctx.fillRect(x + (w - poleW) / 2, cy, poleW, poleH);
80
+ }
81
+ /* ── 3D 렌더 ── */
82
+ export class SignalTower3D extends RealObjectGroup {
83
+ _lightMeshes = [];
84
+ build() {
85
+ super.build();
86
+ const { width, height } = this.component.bounds;
87
+ const { depth } = this.component.state;
88
+ const d = depth || width * 5;
89
+ const radius = Math.min(width, height) / 2;
90
+ // 경광등 부분: width 기반 고정 크기
91
+ const lightH = radius * 1.8;
92
+ const ringH = radius * 0.12;
93
+ const capH = radius * 0.25;
94
+ const baseH = radius * 0.15;
95
+ // 경광등 헤드 총 높이 (등3 + 링4 + 캡)
96
+ const headH = lightH * 3 + ringH * 4 + capH;
97
+ // 폴: 전체 depth에서 헤드+베이스를 뺀 나머지
98
+ const poleH = Math.max(radius * 0.5, d - headH - baseH);
99
+ // ── static parts (merged) ──
100
+ const statics = [];
101
+ // base
102
+ const baseGeo = new THREE.CylinderGeometry(radius * 1.4, radius * 1.4, baseH, 24);
103
+ baseGeo.translate(0, baseH / 2, 0);
104
+ statics.push(baseGeo);
105
+ // pole
106
+ const poleGeo = new THREE.CylinderGeometry(radius * 0.25, radius * 0.25, poleH, 12);
107
+ poleGeo.translate(0, baseH + poleH / 2, 0);
108
+ statics.push(poleGeo);
109
+ let y = baseH + poleH;
110
+ // ring between pole and first light
111
+ const ring0Geo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24);
112
+ ring0Geo.translate(0, y + ringH / 2, 0);
113
+ statics.push(ring0Geo);
114
+ y += ringH;
115
+ // rings between lights
116
+ const lightOrder = ['green', 'yellow', 'red'];
117
+ for (let i = 0; i < 3; i++) {
118
+ y += lightH;
119
+ if (i < 2) {
120
+ const rGeo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24);
121
+ rGeo.translate(0, y + ringH / 2, 0);
122
+ statics.push(rGeo);
123
+ y += ringH;
124
+ }
125
+ }
126
+ // cap
127
+ const capGeo = new THREE.CylinderGeometry(radius * 0.5, radius * 1.05, capH, 24);
128
+ capGeo.translate(0, y + capH / 2, 0);
129
+ statics.push(capGeo);
130
+ const mergedGeo = BufferGeometryUtils.mergeGeometries(statics);
131
+ const staticMat = new THREE.MeshStandardMaterial({
132
+ color: BODY_COLOR,
133
+ roughness: 0.6,
134
+ metalness: 0.3
135
+ });
136
+ const staticMesh = new THREE.Mesh(mergedGeo, staticMat);
137
+ staticMesh.castShadow = true;
138
+ this.object3d.add(staticMesh);
139
+ // ── light meshes (individual for emissive control) ──
140
+ this._lightMeshes = [];
141
+ let ly = baseH + poleH + ringH;
142
+ const value = this.component.value;
143
+ const bitMap = [1, 2, 4]; // green, yellow, red
144
+ for (let i = 0; i < 3; i++) {
145
+ const colorKey = lightOrder[i];
146
+ const isOn = !!(value & bitMap[i]);
147
+ const lightGeo = new THREE.CylinderGeometry(radius, radius, lightH, 24);
148
+ const lightMat = new THREE.MeshStandardMaterial({
149
+ color: isOn ? 0x000000 : LIGHT_COLORS[colorKey].off,
150
+ emissive: isOn ? new THREE.Color(LIGHT_COLORS[colorKey].on) : new THREE.Color(0x000000),
151
+ emissiveIntensity: isOn ? 1.0 : 0,
152
+ roughness: isOn ? 0.1 : 0.7,
153
+ metalness: 0.1
154
+ });
155
+ const mesh = new THREE.Mesh(lightGeo, lightMat);
156
+ mesh.position.y = ly + lightH / 2;
157
+ mesh.castShadow = true;
158
+ this.object3d.add(mesh);
159
+ this._lightMeshes.push(mesh);
160
+ ly += lightH + (i < 2 ? ringH : 0);
161
+ }
162
+ // center vertically
163
+ const totalH = baseH + poleH + headH;
164
+ this.object3d.children.forEach(child => {
165
+ child.position.y -= totalH / 2;
166
+ });
167
+ }
168
+ updateLights(forceOff = false) {
169
+ const value = this.component.value;
170
+ const lightOrder = ['green', 'yellow', 'red'];
171
+ const bitMap = [1, 2, 4]; // green, yellow, red
172
+ for (let i = 0; i < this._lightMeshes.length; i++) {
173
+ const mat = this._lightMeshes[i].material;
174
+ const colorKey = lightOrder[i];
175
+ const isOn = !!(value & bitMap[i]) && !forceOff;
176
+ mat.color.set(isOn ? 0x000000 : LIGHT_COLORS[colorKey].off);
177
+ mat.emissive.set(isOn ? LIGHT_COLORS[colorKey].on : 0x000000);
178
+ mat.emissiveIntensity = isOn ? 1.0 : 0;
179
+ mat.roughness = isOn ? 0.1 : 0.7;
180
+ mat.needsUpdate = true;
181
+ }
182
+ }
183
+ blinkTick() {
184
+ this.updateLights(!isBlinkOn());
185
+ }
186
+ update() {
187
+ super.update();
188
+ this.updateLights();
189
+ }
190
+ updateDimension() {
191
+ this.clear();
192
+ this.build();
193
+ }
194
+ onchange(after, before) {
195
+ super.onchange(after, before);
196
+ if ('value' in after) {
197
+ this.updateLights();
198
+ }
199
+ }
200
+ }
201
+ /* ── Component 클래스 ── */
202
+ const MixedShape = ValueHolder(RectPath(Shape));
203
+ let SignalTower = class SignalTower extends MixedShape {
204
+ _blinkRaf = null;
205
+ _lastBlinkOn = false;
206
+ is3dish() {
207
+ return true;
208
+ }
209
+ buildRealObject() {
210
+ return new SignalTower3D(this);
211
+ }
212
+ get nature() {
213
+ return NATURE;
214
+ }
215
+ async ready() {
216
+ await super.ready();
217
+ if (this.getState('blink')) {
218
+ this._startBlink();
219
+ }
220
+ }
221
+ dispose() {
222
+ this._stopBlink();
223
+ super.dispose();
224
+ }
225
+ _startBlink() {
226
+ if (this._blinkRaf)
227
+ return;
228
+ const tick = () => {
229
+ const on = isBlinkOn();
230
+ if (on !== this._lastBlinkOn) {
231
+ this._lastBlinkOn = on;
232
+ this.invalidate();
233
+ if (this._realObject) {
234
+ ;
235
+ this._realObject.blinkTick();
236
+ }
237
+ }
238
+ this._blinkRaf = requestAnimationFrame(tick);
239
+ };
240
+ this._blinkRaf = requestAnimationFrame(tick);
241
+ }
242
+ _stopBlink() {
243
+ if (!this._blinkRaf)
244
+ return;
245
+ cancelAnimationFrame(this._blinkRaf);
246
+ this._blinkRaf = null;
247
+ // 정상 점등 상태로 복원
248
+ this.invalidate();
249
+ if (this._realObject) {
250
+ ;
251
+ this._realObject.updateLights();
252
+ }
253
+ }
254
+ onchange(after, before) {
255
+ super.onchange(after, before);
256
+ if ('value' in after || 'blink' in after) {
257
+ this.invalidate();
258
+ if (this.getState('blink')) {
259
+ this._startBlink();
260
+ }
261
+ else {
262
+ this._stopBlink();
263
+ }
264
+ }
265
+ }
266
+ render(ctx) {
267
+ const { left, top, width, height } = this.bounds;
268
+ renderSignalTower(ctx, left, top, width, height, this.value, !!this.getState('blink'));
269
+ }
270
+ };
271
+ SignalTower = __decorate([
272
+ sceneComponent('signal-tower')
273
+ ], SignalTower);
274
+ export { SignalTower };
275
+ //# sourceMappingURL=signal-tower.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-tower.js","sourceRoot":"","sources":["../src/signal-tower.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport {\n Component,\n ComponentNature,\n RealObjectGroup,\n RealObject,\n RectPath,\n Shape,\n ValueHolder,\n sceneComponent\n} from '@hatiolab/things-scene'\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\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 property: 'value'\n },\n {\n type: 'checkbox',\n label: 'blink',\n name: 'blink',\n property: 'blink'\n }\n ],\n help: 'scene/component/signal-tower'\n}\n\n/* ── 색상 상수 ── */\nconst LIGHT_COLORS = {\n red: { on: '#cc0000', off: '#1a0505' },\n yellow: { on: '#cc8800', off: '#1a1400' },\n green: { on: '#00bb00', off: '#051a05' }\n} as const\n\nconst BODY_COLOR = '#333333'\nconst POLE_COLOR = '#888888'\nconst RING_COLOR = '#222222'\n\n/* ── 2D 렌더 ── */\n\nconst BLINK_PERIOD = 500 // ms\n\nfunction isBlinkOn() {\n return Math.floor(Date.now() / BLINK_PERIOD) % 2 === 0\n}\n\nfunction renderSignalTower(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, value: number, blink: boolean) {\n const sep = Math.max(1, h * 0.01)\n const poleH = h * 0.08\n const lightH = (h - sep * 2 - poleH) / 3\n\n const blinkVisible = !blink || isBlinkOn()\n const lights = [\n { color: LIGHT_COLORS.red, on: !!(value & 4) && blinkVisible },\n { color: LIGHT_COLORS.yellow, on: !!(value & 2) && blinkVisible },\n { color: LIGHT_COLORS.green, on: !!(value & 1) && blinkVisible }\n ]\n\n let cy = y\n\n for (let i = 0; i < 3; i++) {\n const light = lights[i]\n\n // light band — full width\n ctx.fillStyle = light.on ? light.color.on : light.color.off\n ctx.fillRect(x, cy, w, lightH)\n\n // ON glow overlay\n if (light.on) {\n const cx = x + w / 2\n const my = cy + lightH / 2\n const grad = ctx.createRadialGradient(cx, my, 0, cx, my, w * 0.6)\n grad.addColorStop(0, '#ffffff88')\n grad.addColorStop(1, '#ffffff00')\n ctx.fillStyle = grad\n ctx.fillRect(x, cy, w, lightH)\n }\n\n cy += lightH\n\n // thin separator between lights\n if (i < 2) {\n ctx.fillStyle = RING_COLOR\n ctx.fillRect(x, cy, w, sep)\n cy += sep\n }\n }\n\n // pole stub\n const poleW = w * 0.3\n ctx.fillStyle = POLE_COLOR\n ctx.fillRect(x + (w - poleW) / 2, cy, poleW, poleH)\n}\n\n/* ── 3D 렌더 ── */\n\nexport class SignalTower3D extends RealObjectGroup {\n private _lightMeshes: THREE.Mesh[] = []\n\n build() {\n super.build()\n\n const { width, height } = this.component.bounds\n const { depth } = this.component.state\n const d = depth || width * 5\n\n const radius = Math.min(width, height) / 2\n\n // 경광등 부분: width 기반 고정 크기\n const lightH = radius * 1.8\n const ringH = radius * 0.12\n const capH = radius * 0.25\n const baseH = radius * 0.15\n\n // 경광등 헤드 총 높이 (등3 + 링4 + 캡)\n const headH = lightH * 3 + ringH * 4 + capH\n\n // 폴: 전체 depth에서 헤드+베이스를 뺀 나머지\n const poleH = Math.max(radius * 0.5, d - headH - baseH)\n\n // ── static parts (merged) ──\n const statics: THREE.BufferGeometry[] = []\n\n // base\n const baseGeo = new THREE.CylinderGeometry(radius * 1.4, radius * 1.4, baseH, 24)\n baseGeo.translate(0, baseH / 2, 0)\n statics.push(baseGeo)\n\n // pole\n const poleGeo = new THREE.CylinderGeometry(radius * 0.25, radius * 0.25, poleH, 12)\n poleGeo.translate(0, baseH + poleH / 2, 0)\n statics.push(poleGeo)\n\n let y = baseH + poleH\n\n // ring between pole and first light\n const ring0Geo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24)\n ring0Geo.translate(0, y + ringH / 2, 0)\n statics.push(ring0Geo)\n y += ringH\n\n // rings between lights\n const lightOrder = ['green', 'yellow', 'red'] as const\n for (let i = 0; i < 3; i++) {\n y += lightH\n if (i < 2) {\n const rGeo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24)\n rGeo.translate(0, y + ringH / 2, 0)\n statics.push(rGeo)\n y += ringH\n }\n }\n\n // cap\n const capGeo = new THREE.CylinderGeometry(radius * 0.5, radius * 1.05, capH, 24)\n capGeo.translate(0, y + capH / 2, 0)\n statics.push(capGeo)\n\n const mergedGeo = BufferGeometryUtils.mergeGeometries(statics)\n const staticMat = new THREE.MeshStandardMaterial({\n color: BODY_COLOR,\n roughness: 0.6,\n metalness: 0.3\n })\n const staticMesh = new THREE.Mesh(mergedGeo, staticMat)\n staticMesh.castShadow = true\n this.object3d.add(staticMesh)\n\n // ── light meshes (individual for emissive control) ──\n this._lightMeshes = []\n let ly = baseH + poleH + ringH\n const value = (this.component as unknown as SignalTower).value\n const bitMap = [1, 2, 4] // green, yellow, red\n\n for (let i = 0; i < 3; i++) {\n const colorKey = lightOrder[i]\n const isOn = !!(value & bitMap[i])\n\n const lightGeo = new THREE.CylinderGeometry(radius, radius, lightH, 24)\n const lightMat = new THREE.MeshStandardMaterial({\n color: isOn ? 0x000000 : LIGHT_COLORS[colorKey].off,\n emissive: isOn ? new THREE.Color(LIGHT_COLORS[colorKey].on) : new THREE.Color(0x000000),\n emissiveIntensity: isOn ? 1.0 : 0,\n roughness: isOn ? 0.1 : 0.7,\n metalness: 0.1\n })\n\n const mesh = new THREE.Mesh(lightGeo, lightMat)\n mesh.position.y = ly + lightH / 2\n mesh.castShadow = true\n this.object3d.add(mesh)\n this._lightMeshes.push(mesh)\n\n ly += lightH + (i < 2 ? ringH : 0)\n }\n\n // center vertically\n const totalH = baseH + poleH + headH\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n\n updateLights(forceOff = false) {\n const value = (this.component as unknown as SignalTower).value\n const lightOrder = ['green', 'yellow', 'red'] as const\n const bitMap = [1, 2, 4] // green, yellow, red\n\n for (let i = 0; i < this._lightMeshes.length; i++) {\n const mat = this._lightMeshes[i].material as THREE.MeshStandardMaterial\n const colorKey = lightOrder[i]\n const isOn = !!(value & bitMap[i]) && !forceOff\n\n mat.color.set(isOn ? 0x000000 : LIGHT_COLORS[colorKey].off)\n mat.emissive.set(isOn ? LIGHT_COLORS[colorKey].on : 0x000000)\n mat.emissiveIntensity = isOn ? 1.0 : 0\n mat.roughness = isOn ? 0.1 : 0.7\n mat.needsUpdate = true\n }\n }\n\n blinkTick() {\n this.updateLights(!isBlinkOn())\n }\n\n update() {\n super.update()\n this.updateLights()\n }\n\n updateDimension() {\n this.clear()\n this.build()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n super.onchange(after, before)\n\n if ('value' in after) {\n this.updateLights()\n }\n }\n}\n\n/* ── Component 클래스 ── */\n\nconst MixedShape = ValueHolder(RectPath(Shape))\n\n@sceneComponent('signal-tower')\nexport class SignalTower extends MixedShape {\n private _blinkRaf: number | null = null\n private _lastBlinkOn: boolean = false\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new SignalTower3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n async ready() {\n await super.ready()\n if (this.getState('blink')) {\n this._startBlink()\n }\n }\n\n dispose() {\n this._stopBlink()\n super.dispose()\n }\n\n private _startBlink() {\n if (this._blinkRaf) return\n\n const tick = () => {\n const on = isBlinkOn()\n if (on !== this._lastBlinkOn) {\n this._lastBlinkOn = on\n this.invalidate()\n if (this._realObject) {\n ;(this._realObject as SignalTower3D).blinkTick()\n }\n }\n this._blinkRaf = requestAnimationFrame(tick)\n }\n\n this._blinkRaf = requestAnimationFrame(tick)\n }\n\n private _stopBlink() {\n if (!this._blinkRaf) return\n cancelAnimationFrame(this._blinkRaf)\n this._blinkRaf = null\n // 정상 점등 상태로 복원\n this.invalidate()\n if (this._realObject) {\n ;(this._realObject as SignalTower3D).updateLights()\n }\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n super.onchange(after, before)\n\n if ('value' in after || 'blink' in after) {\n this.invalidate()\n\n if (this.getState('blink')) {\n this._startBlink()\n } else {\n this._stopBlink()\n }\n }\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n renderSignalTower(ctx, left, top, width, height, this.value, !!this.getState('blink'))\n }\n\n}\n"]}
package/dist/sphere.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- import { ComponentNature, Ellipse } from '@hatiolab/things-scene';
2
- import { RealObject } from './threed/real-object.js';
3
- import { RealObjectMesh } from './threed/real-object-mesh.js';
1
+ import { ComponentNature, Ellipse, RealObject, RealObjectMesh } from '@hatiolab/things-scene';
4
2
  export declare class Sphere3D extends RealObjectMesh {
5
3
  buildGeometry(): void;
6
4
  }
package/dist/sphere.js CHANGED
@@ -2,9 +2,8 @@ import { __decorate } from "tslib";
2
2
  /*
3
3
  * Copyright © HatioLab Inc. All rights reserved.
4
4
  */
5
- import { Ellipse, sceneComponent } from '@hatiolab/things-scene';
5
+ import { Ellipse, sceneComponent, RealObjectMesh } from '@hatiolab/things-scene';
6
6
  import * as THREE from 'three';
7
- import { RealObjectMesh } from './threed/real-object-mesh.js';
8
7
  const NATURE = {
9
8
  mutable: false,
10
9
  resizable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"sphere.js","sourceRoot":"","sources":["../src/sphere.ts"],"names":[],"mappings":";AAAA;;GAEG;AACH,OAAO,EAA8B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,EAAE;IACd,IAAI,EAAE,wBAAwB;CAC/B,CAAA;AAED,MAAM,OAAO,QAAS,SAAQ,cAAc;IAC1C,aAAa;QACX,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QAExD,IAAI,QAAQ,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QAE7B,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAA;IACnC,CAAC;CACF;AAGM,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,OAAO;IACjC,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAZY,MAAM;IADlB,cAAc,CAAC,QAAQ,CAAC;GACZ,MAAM,CAYlB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Component, ComponentNature, Ellipse, sceneComponent } from '@hatiolab/things-scene'\nimport * as THREE from 'three'\nimport { RealObject } from './threed/real-object.js'\nimport { RealObjectMesh } from './threed/real-object-mesh.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [],\n help: 'scene/component/sphere'\n}\n\nexport class Sphere3D extends RealObjectMesh {\n buildGeometry() {\n var { depth = 0, rx = 0, ry = 0 } = this.component.state\n\n let geometry = new THREE.SphereGeometry(1, 32, 16)\n geometry.scale(rx, depth, ry)\n\n this.object3d.geometry = geometry\n }\n}\n\n@sceneComponent('sphere')\nexport class Sphere extends Ellipse {\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Sphere3D(this)\n }\n\n get nature() {\n return NATURE\n }\n}\n"]}
1
+ {"version":3,"file":"sphere.js","sourceRoot":"","sources":["../src/sphere.ts"],"names":[],"mappings":";AAAA;;GAEG;AACH,OAAO,EAA8B,OAAO,EAAE,cAAc,EAAc,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACxH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,EAAE;IACd,IAAI,EAAE,wBAAwB;CAC/B,CAAA;AAED,MAAM,OAAO,QAAS,SAAQ,cAAc;IAC1C,aAAa;QACX,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QAExD,IAAI,QAAQ,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QAE7B,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAA;IACnC,CAAC;CACF;AAGM,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,OAAO;IACjC,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,QAAQ,CAAC,IAAW,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAZY,MAAM;IADlB,cAAc,CAAC,QAAQ,CAAC;GACZ,MAAM,CAYlB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Component, ComponentNature, Ellipse, sceneComponent, RealObject, RealObjectMesh } from '@hatiolab/things-scene'\nimport * as THREE from 'three'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [],\n help: 'scene/component/sphere'\n}\n\nexport class Sphere3D extends RealObjectMesh {\n buildGeometry() {\n var { depth = 0, rx = 0, ry = 0 } = this.component.state\n\n let geometry = new THREE.SphereGeometry(1, 32, 16)\n geometry.scale(rx, depth, ry)\n\n this.object3d.geometry = geometry\n }\n}\n\n@sceneComponent('sphere')\nexport class Sphere extends Ellipse {\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Sphere3D(this as any)\n }\n\n get nature(): ComponentNature {\n return NATURE\n }\n}\n"]}
package/dist/sprite.d.ts CHANGED
@@ -1,6 +1,235 @@
1
- import { ComponentNature, Shape } from '@hatiolab/things-scene';
2
- import { RealObject } from './threed/real-object.js';
3
- declare const Sprite_base: typeof Shape;
1
+ import { Component, ComponentNature, Shape, RealObject } from '@hatiolab/things-scene';
2
+ declare const Sprite_base: (new (...args: any[]) => {
3
+ contains(x: any, y: any): boolean;
4
+ get path(): {
5
+ x: any;
6
+ y: any;
7
+ }[];
8
+ set path(path: {
9
+ x: any;
10
+ y: any;
11
+ }[]): any;
12
+ get anchors(): {
13
+ name: string;
14
+ position: {
15
+ x: any;
16
+ y: any;
17
+ };
18
+ }[];
19
+ get bounds(): any;
20
+ set bounds(bounds: any): any;
21
+ render(ctx: any): void;
22
+ _app: any;
23
+ _model: any;
24
+ _state: any;
25
+ _delta: any;
26
+ _animation: any;
27
+ _animate: any;
28
+ _parent: any;
29
+ _disposed: any;
30
+ _textHidden: any;
31
+ _text_substitutor: any;
32
+ _value_substitutor: any;
33
+ _mappings: any;
34
+ _realObject: import("@hatiolab/things-scene").IRealObject | undefined;
35
+ _cachedState: any;
36
+ updatedAt: any;
37
+ fontSize: any;
38
+ __cache__: any;
39
+ created(): void;
40
+ added(parent: any): void;
41
+ removed(parent: any): void;
42
+ ready(): Promise<void>;
43
+ touch(): void;
44
+ clearCache(...attrs: any[]): void;
45
+ removeSelf(completely: any): void;
46
+ resetAnimation(): void;
47
+ dispose(): void;
48
+ get nature(): import("@hatiolab/things-scene").ComponentNature;
49
+ get disposed(): boolean;
50
+ isLayer(): boolean;
51
+ isGroup(): boolean;
52
+ isContainer(): this is import("@hatiolab/things-scene/dist-types/types/component").Container;
53
+ isLine(): boolean;
54
+ isRoot(): boolean;
55
+ isRootModel(): boolean;
56
+ is3dish(): boolean;
57
+ isIn3DSpace(): boolean;
58
+ isTemplate(): boolean;
59
+ isHTMLElement(): boolean;
60
+ isConnectable(): boolean;
61
+ isIdentifiable(): boolean;
62
+ isPositionable(): boolean;
63
+ replaceRefids(replaceMap: any): void;
64
+ get(property: any): any;
65
+ set(props: any, propval?: any): any;
66
+ getState(property: any): any;
67
+ setState(props: any, propval?: any): any;
68
+ get model(): any;
69
+ get state(): any;
70
+ get hierarchy(): any;
71
+ get volatile(): never[];
72
+ _applyProps(target: any, props: any, options: any): any;
73
+ move(offset: {
74
+ x: number;
75
+ y: number;
76
+ }, ...args: boolean[]): void;
77
+ symmetryX(x?: number): void;
78
+ symmetryY(y: number): void;
79
+ adjustResize(bounds: import("@hatiolab/things-scene").BOUNDS, origin_bounds: import("@hatiolab/things-scene").BOUNDS, diagonal: boolean): any;
80
+ adjustRotation(rotation: number, step: boolean): any;
81
+ outline(progress: number): any;
82
+ get center(): import("@hatiolab/things-scene").POINT;
83
+ set center(p: import("@hatiolab/things-scene").POINT): any;
84
+ get location(): import("@hatiolab/things-scene").POINT;
85
+ set location(l: import("@hatiolab/things-scene").POINT): any;
86
+ get rotate(): import("@hatiolab/things-scene").POINT;
87
+ set rotate(r: import("@hatiolab/things-scene").POINT): any;
88
+ get dimension(): import("@hatiolab/things-scene").DIMENSION;
89
+ set dimension(d: import("@hatiolab/things-scene").DIMENSION): any;
90
+ get drawPath(): import("@hatiolab/things-scene").POINT[];
91
+ get rotatePoint(): import("@hatiolab/things-scene").POINT;
92
+ get mutable(): boolean;
93
+ get resizable(): boolean;
94
+ get rotatable(): boolean;
95
+ buildRealObject(): import("@hatiolab/things-scene").IRealObject | undefined;
96
+ get realObject(): import("@hatiolab/things-scene").IRealObject | undefined;
97
+ draw(context?: import("@hatiolab/things-scene").SceneRenderContext): void;
98
+ prerender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
99
+ postrender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
100
+ prepare(resolve: (component: Component) => void, reject: (reason: any) => void): void;
101
+ prepareIf(condition: boolean): void;
102
+ drawText(context: import("@hatiolab/things-scene").SceneRenderContext): void;
103
+ drawStroke(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
104
+ drawFill(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
105
+ get strokeStyle(): any;
106
+ set strokeStyle(v: any): any;
107
+ get fillStyle(): any;
108
+ set fillStyle(v: any): any;
109
+ get fontColor(): string;
110
+ set fontColor(v: string): any;
111
+ get rotation(): number;
112
+ set rotation(v: number): any;
113
+ get decorators(): string[];
114
+ get decotag(): string;
115
+ get hidden(): boolean;
116
+ set hidden(v: boolean): any;
117
+ get tag(): string;
118
+ set tag(v: string): any;
119
+ get appendum(): any;
120
+ set appendum(v: any): any;
121
+ defaultTextSubstitutor(): any;
122
+ textLines(context?: import("@hatiolab/things-scene").SceneRenderContext): any;
123
+ get font(): string;
124
+ get lineHeight(): number;
125
+ get textSubstitutor(): () => string;
126
+ get text(): string;
127
+ set text(v: string): any;
128
+ get textBounds(): import("@hatiolab/things-scene").BOUNDS;
129
+ get textRotation(): number;
130
+ get textHidden(): boolean;
131
+ set textHidden(v: boolean): any;
132
+ get hasTextProperty(): boolean;
133
+ animate(opts: import("@hatiolab/things-scene/dist-types/animation/interfaces").AnimationConfig): any;
134
+ effect(context: import("@hatiolab/things-scene").SceneRenderContext, model: any): any;
135
+ serialize(...others: any[]): any;
136
+ trim(): void;
137
+ closeScene(data: any): void;
138
+ delta(attr?: string | object, value?: any): any;
139
+ invalidate(): void;
140
+ get value(): any;
141
+ set value(v: any): any;
142
+ get data(): any;
143
+ set data(v: any): any;
144
+ set tap(v: any): any;
145
+ get mappings(): any[];
146
+ get retention(): number;
147
+ get animation(): import("@hatiolab/things-scene/dist-types/animation/interfaces").AnimationController | undefined;
148
+ get started(): boolean;
149
+ set started(v: boolean): any;
150
+ get controls(): import("@hatiolab/things-scene").Control[] | undefined;
151
+ findFirst(finder: string | ((c: Component) => boolean), ...others: any[]): any;
152
+ findAll(s: string | ((c: Component) => boolean), ...others: any[]): any;
153
+ capture(x: number, y: number, except?: (c: Component) => boolean): any;
154
+ findAnchor(name: string): any;
155
+ isDescendible(container: Component): any;
156
+ getContext(component?: unknown): any;
157
+ get root(): Component;
158
+ get rootModel(): Component;
159
+ get parent(): Component;
160
+ set parent(v: Component): any;
161
+ get scalable(): boolean;
162
+ get stuck(): boolean;
163
+ get capturable(): boolean;
164
+ get position(): string;
165
+ get origin(): string;
166
+ get offset(): import("@hatiolab/things-scene").POINT;
167
+ get app(): import("@hatiolab/things-scene").ApplicationContext;
168
+ drawEffect(context: import("@hatiolab/things-scene").SceneRenderContext): void;
169
+ prepareFill(resolve: Function, reject: Function): void;
170
+ prepareFillIf(condition: boolean): void;
171
+ onchangeFill(after: Record<string, any>, before: Record<string, any>): void;
172
+ drawImage(context: import("@hatiolab/things-scene").SceneRenderContext, image: HTMLImageElement, left: number, top: number, width: number, height: number): void;
173
+ mutateBounds(logic: ((bounds: import("@hatiolab/things-scene").BOUNDS) => import("@hatiolab/things-scene").BOUNDS | void) | null, context?: any): void;
174
+ mutatePath(beforeLogic: ((path: import("@hatiolab/things-scene").POINT[]) => import("@hatiolab/things-scene").POINT[] | void) | null, afterLogic: ((path: import("@hatiolab/things-scene").POINT[]) => import("@hatiolab/things-scene").POINT[] | void) | null, context?: any): void;
175
+ access(accessor: string, data: any): any;
176
+ substitute(template: string, data: any): any;
177
+ onchangeMappings(after: Record<string, any>, before: Record<string, any>): void;
178
+ onchangeData(after: Record<string, any>, before: Record<string, any>): void;
179
+ buildMappings(): void;
180
+ executeMappings(force?: boolean): void;
181
+ disposeMappings(): void;
182
+ ondropfile(transfered: FileList, files: string[]): void;
183
+ transcoordS2P(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
184
+ transcoordP2S(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
185
+ transcoordS2T(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
186
+ transcoordT2P(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
187
+ transcoordT2S(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
188
+ transcoordS2TR(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
189
+ transcoordS2O(x: number, y: number, target: Component): import("@hatiolab/things-scene").POINT;
190
+ transcoordC2S(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
191
+ transcoordS2C(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
192
+ toParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
193
+ fromParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
194
+ toScene(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
195
+ fromScene(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
196
+ toLocal(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
197
+ toGlobal(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
198
+ toOther(x: number, y: number, target: Component): import("@hatiolab/things-scene").POINT;
199
+ on(name: string | object, callback: Function, context?: any): any;
200
+ off(name?: string | object, callback?: Function, context?: any): any;
201
+ once(name: string | object, callback: Function, context?: any): any;
202
+ trigger(name: string, ...args: any[]): any;
203
+ delegate_on(delegator: any): any;
204
+ delegate_off(delegator: any): any;
205
+ onchange(after: Record<string, any>, before: Record<string, any>): void;
206
+ calculateBounds?(): void;
207
+ oncreate_element?(element: HTMLElement): void;
208
+ removeComponent(component: Component, ghost?: boolean): void;
209
+ addComponent(component: Component, ghost?: boolean): void;
210
+ insertComponentAt(component: Component, index: number, ghost?: boolean): void;
211
+ getOverlay(component: Component): HTMLElement | undefined;
212
+ findById(id: string): Component | undefined;
213
+ findByRefid(ref: string | number): Component | undefined;
214
+ findAllById(id: string): Component[];
215
+ resize(): void;
216
+ fit(type?: string): void;
217
+ get components(): Component[] | undefined;
218
+ get layout(): any;
219
+ get auxOverlay(): HTMLElement | undefined;
220
+ get isReady(): boolean;
221
+ get unitScale(): number;
222
+ get selected(): Component[];
223
+ set selected(_v: Component[]): any;
224
+ get focused(): Component | null;
225
+ set focused(_v: Component | null): any;
226
+ get hasSameParentForAllSelected(): boolean;
227
+ set hasSameParentForAllSelected(_v: boolean): any;
228
+ get fitMode(): string | undefined;
229
+ set fitMode(_v: string | undefined): any;
230
+ get element(): HTMLElement | null;
231
+ set element(_v: HTMLElement | null): any;
232
+ }) & typeof Shape;
4
233
  export declare class Sprite extends Sprite_base {
5
234
  is3dish(): boolean;
6
235
  buildRealObject(): RealObject | undefined;
package/dist/sprite.js CHANGED
@@ -2,8 +2,7 @@
2
2
  * Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
  import { __decorate } from "tslib";
5
- import { RectPath, Shape, sceneComponent } from '@hatiolab/things-scene';
6
- import { RealObjectSprite2D } from './threed/real-object-sprite-2d.js';
5
+ import { RectPath, Shape, sceneComponent, RealObjectSprite2D } from '@hatiolab/things-scene';
7
6
  const NATURE = {
8
7
  mutable: false,
9
8
  resizable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"sprite.js","sourceRoot":"","sources":["../src/sprite.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAA8B,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AAEtE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,EAAE;CACf,CAAA;AAGM,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,QAAQ,CAAC,KAAK,CAAC;IACzC,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACrC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAZY,MAAM;IADlB,cAAc,CAAC,QAAQ,CAAC;GACZ,MAAM,CAYlB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { Component, ComponentNature, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\nimport { RealObject } from './threed/real-object.js'\nimport { RealObjectSprite2D } from './threed/real-object-sprite-2d.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: []\n}\n\n@sceneComponent('sprite')\nexport class Sprite extends RectPath(Shape) {\n is3dish(): boolean {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new RealObjectSprite2D(this)\n }\n\n get nature() {\n return NATURE\n }\n}\n"]}
1
+ {"version":3,"file":"sprite.js","sourceRoot":"","sources":["../src/sprite.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAA8B,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAc,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAEpI,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,EAAE;CACf,CAAA;AAGM,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,QAAQ,CAAC,KAAK,CAAC;IACzC,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,kBAAkB,CAAC,IAAW,CAAC,CAAA;IAC5C,CAAC;IAED,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAZY,MAAM;IADlB,cAAc,CAAC,QAAQ,CAAC;GACZ,MAAM,CAYlB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { Component, ComponentNature, RectPath, Shape, sceneComponent, RealObject, RealObjectSprite2D } from '@hatiolab/things-scene'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: []\n}\n\n@sceneComponent('sprite')\nexport class Sprite extends RectPath(Shape) {\n is3dish(): boolean {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new RealObjectSprite2D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n}\n"]}
package/dist/stock.d.ts CHANGED
@@ -1,18 +1,30 @@
1
- import { Component, Model } from '@hatiolab/things-scene';
1
+ import { Component, RealObject } from '@hatiolab/things-scene';
2
2
  import * as THREE from 'three';
3
- import { RealObject } from './threed/real-object.js';
4
- import { Visualizer } from './visualizer.js';
3
+ /**
4
+ * Stock material/legend 정보를 제공하는 컴포넌트 인터페이스.
5
+ * Visualizer와 RackTable 모두 이를 구현한다.
6
+ */
7
+ export interface StockMaterialProvider {
8
+ _stock_materials: THREE.Material[];
9
+ _default_material?: THREE.Material;
10
+ _empty_material?: THREE.Material;
11
+ legendTarget?: Component;
12
+ hideEmptyStock?: boolean;
13
+ }
5
14
  export declare class Stock extends RealObject<THREE.Mesh> {
6
15
  static defaultMaterial: THREE.MeshStandardMaterial;
16
+ static defaultEmptyMaterial: THREE.MeshStandardMaterial;
7
17
  static stockGeometry: THREE.BoxGeometry;
8
18
  _hideEmptyStock: boolean;
9
- _focused: boolean;
10
- _focusedAt?: number;
11
- model: Model;
12
- constructor(component: Component, model: Model);
13
- protected getObject3dInstance(): THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>;
19
+ model: any;
20
+ constructor(component: Component, model: any);
21
+ protected getObject3dInstance(): THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>;
22
+ /**
23
+ * 가장 가까운 StockMaterialProvider 조상을 찾는다 (RackTable 또는 Visualizer).
24
+ */
25
+ get provider(): StockMaterialProvider | undefined;
26
+ private get _legendStatus();
14
27
  getMaterial(index: number): THREE.Material;
15
- get visualizer(): Visualizer | undefined;
16
28
  get stockMaterials(): THREE.Material[];
17
29
  get userDefineDefaultMaterial(): THREE.Material;
18
30
  get emptyMaterial(): THREE.Material;
@@ -20,7 +32,7 @@ export declare class Stock extends RealObject<THREE.Mesh> {
20
32
  createStock(w: number, h: number, d: number): void;
21
33
  onchangeStockData(data: any): void;
22
34
  onBeforeRender: () => void;
23
- onmouseup(e: MouseEvent, visualizer: Visualizer, callback: (arg: {
35
+ onmouseup(e: MouseEvent, _context: unknown, callback: (arg: {
24
36
  data: any;
25
37
  location: string;
26
38
  }) => void): void;