@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,263 @@
1
+ import { Component, Properties, ComponentNature, Shape, RealObject } from '@hatiolab/things-scene';
2
+ export declare class Carrier3D extends RealObject {
3
+ build(): void;
4
+ }
5
+ declare const Carrier_base: (new (...args: any[]) => {
6
+ contains(x: number, y: number): boolean;
7
+ get path(): {
8
+ x: any;
9
+ y: any;
10
+ }[];
11
+ set path(path: {
12
+ x: any;
13
+ y: any;
14
+ }[]): any;
15
+ get anchors(): {
16
+ name: string;
17
+ position: {
18
+ x: any;
19
+ y: any;
20
+ };
21
+ }[];
22
+ get bounds(): any;
23
+ set bounds(bounds: any): any;
24
+ render(ctx: CanvasRenderingContext2D): void;
25
+ _app: any;
26
+ _model: any;
27
+ _state: any;
28
+ _delta: any;
29
+ _animation: any;
30
+ _animate: any;
31
+ _parent: any;
32
+ _disposed: any;
33
+ _textHidden: any;
34
+ _text_substitutor: any;
35
+ _value_substitutor: any;
36
+ _mappings: any;
37
+ _realObject: import("@hatiolab/things-scene").IRealObject | undefined;
38
+ _cachedState: any;
39
+ updatedAt: any;
40
+ fontSize: any;
41
+ __cache__: any;
42
+ created(): void;
43
+ added(parent: any): void;
44
+ removed(parent: any): void;
45
+ ready(): Promise<void>;
46
+ touch(): void;
47
+ clearCache(...attrs: any[]): void;
48
+ removeSelf(completely: any): void;
49
+ resetAnimation(): void;
50
+ dispose(): void;
51
+ get nature(): import("@hatiolab/things-scene").ComponentNature;
52
+ get disposed(): boolean;
53
+ isLayer(): boolean;
54
+ isGroup(): boolean;
55
+ isContainer(): this is import("@hatiolab/things-scene/dist-types/types/component").Container;
56
+ isLine(): boolean;
57
+ isRoot(): boolean;
58
+ isRootModel(): boolean;
59
+ is3dish(): boolean;
60
+ get is3dMode(): boolean;
61
+ isIn3DSpace(): boolean;
62
+ isTemplate(): boolean;
63
+ isHTMLElement(): boolean;
64
+ isConnectable(): boolean;
65
+ isIdentifiable(): boolean;
66
+ isPositionable(): boolean;
67
+ replaceRefids(replaceMap: any): void;
68
+ get(property: any): any;
69
+ set(props: any, propval?: any): any;
70
+ getState(property: any): any;
71
+ setState(props: any, propval?: any): any;
72
+ get model(): any;
73
+ get state(): any;
74
+ get hierarchy(): any;
75
+ get volatile(): never[];
76
+ _applyProps(target: any, props: any, options: any): any;
77
+ move(offset: {
78
+ x: number;
79
+ y: number;
80
+ }, ...args: boolean[]): void;
81
+ symmetryX(x?: number): void;
82
+ symmetryY(y: number): void;
83
+ adjustResize(bounds: import("@hatiolab/things-scene").BOUNDS, origin_bounds: import("@hatiolab/things-scene").BOUNDS, diagonal: boolean): {
84
+ left: any;
85
+ top: any;
86
+ width: any;
87
+ height: any;
88
+ };
89
+ adjustRotation(rotation: number, step: boolean): number;
90
+ outline(progress: number): any;
91
+ get center(): import("@hatiolab/things-scene").POINT;
92
+ set center(p: import("@hatiolab/things-scene").POINT): any;
93
+ get location(): import("@hatiolab/things-scene").POINT;
94
+ set location(l: import("@hatiolab/things-scene").POINT): any;
95
+ get rotate(): import("@hatiolab/things-scene").POINT;
96
+ set rotate(r: import("@hatiolab/things-scene").POINT): any;
97
+ get dimension(): import("@hatiolab/things-scene").DIMENSION;
98
+ set dimension(d: import("@hatiolab/things-scene").DIMENSION): any;
99
+ get drawPath(): import("@hatiolab/things-scene").POINT[];
100
+ get rotatePoint(): import("@hatiolab/things-scene").POINT;
101
+ get mutable(): boolean;
102
+ get resizable(): boolean;
103
+ get rotatable(): boolean;
104
+ buildRealObject(): import("@hatiolab/things-scene").IRealObject | undefined;
105
+ get realObject(): import("@hatiolab/things-scene").IRealObject | undefined;
106
+ draw(context?: import("@hatiolab/things-scene").SceneRenderContext): void;
107
+ prerender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
108
+ postrender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
109
+ prepare(resolve: (component: Component) => void, reject: (reason: any) => void): void;
110
+ prepareIf(condition: boolean): void;
111
+ drawText(context: import("@hatiolab/things-scene").SceneRenderContext): void;
112
+ drawStroke(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
113
+ drawFill(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
114
+ get strokeStyle(): any;
115
+ set strokeStyle(v: any): any;
116
+ get fillStyle(): any;
117
+ set fillStyle(v: any): any;
118
+ get fontColor(): string;
119
+ set fontColor(v: string): any;
120
+ get rotation(): number;
121
+ set rotation(v: number): any;
122
+ get decorators(): string[];
123
+ get decotag(): string;
124
+ get hidden(): boolean;
125
+ set hidden(v: boolean): any;
126
+ get tag(): string;
127
+ set tag(v: string): any;
128
+ get appendum(): any;
129
+ set appendum(v: any): any;
130
+ defaultTextSubstitutor(): string;
131
+ textLines(context?: import("@hatiolab/things-scene").SceneRenderContext): any[][];
132
+ get font(): string;
133
+ get lineHeight(): number;
134
+ get textSubstitutor(): () => string;
135
+ get text(): string;
136
+ set text(v: string): any;
137
+ get textBounds(): import("@hatiolab/things-scene").BOUNDS;
138
+ get textRotation(): number;
139
+ get textHidden(): boolean;
140
+ set textHidden(v: boolean): any;
141
+ get hasTextProperty(): boolean;
142
+ animate(opts: import("@hatiolab/things-scene").AnimationConfig): any;
143
+ effect(context: import("@hatiolab/things-scene").SceneRenderContext, model: any): void;
144
+ serialize(...others: any[]): string;
145
+ trim(): void;
146
+ closeScene(data: any): void;
147
+ delta(attr?: string | object, value?: any): any;
148
+ invalidate(): void;
149
+ get value(): any;
150
+ set value(v: any): any;
151
+ get data(): any;
152
+ set data(v: any): any;
153
+ set tap(v: any): any;
154
+ get mappings(): any[];
155
+ get retention(): number;
156
+ get animation(): import("@hatiolab/things-scene").AnimationController | undefined;
157
+ get started(): boolean;
158
+ set started(v: boolean): any;
159
+ get controls(): import("@hatiolab/things-scene").Control[] | undefined;
160
+ findFirst(finder: string | ((c: Component) => boolean), ...others: any[]): Component | undefined;
161
+ findAll(s: string | ((c: Component) => boolean), ...others: any[]): any[] | undefined;
162
+ capture(x: number, y: number, except?: (c: Component) => boolean): any;
163
+ findAnchor(name: string): any;
164
+ isDescendible(container: Component): boolean;
165
+ getContext(component?: unknown): any;
166
+ get root(): Component;
167
+ get rootModel(): Component;
168
+ get parent(): Component;
169
+ set parent(v: Component): any;
170
+ get scalable(): boolean;
171
+ get stuck(): boolean;
172
+ get capturable(): boolean;
173
+ get position(): string;
174
+ get origin(): string;
175
+ get offset(): import("@hatiolab/things-scene").POINT;
176
+ get app(): import("@hatiolab/things-scene").ApplicationContext;
177
+ drawEffect(context: import("@hatiolab/things-scene").SceneRenderContext): void;
178
+ prepareFill(resolve: Function, reject: Function): void;
179
+ prepareFillIf(condition: boolean): void;
180
+ onchangeFill(after: Record<string, any>, before: Record<string, any>): void;
181
+ drawImage(context: import("@hatiolab/things-scene").SceneRenderContext, image: HTMLImageElement, left: number, top: number, width: number, height: number): void;
182
+ mutateBounds(logic: ((bounds: import("@hatiolab/things-scene").BOUNDS) => import("@hatiolab/things-scene").BOUNDS | void) | null, context?: any): void;
183
+ 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;
184
+ access(accessor: string): any;
185
+ substitute(template: string, data: any): string | undefined;
186
+ onchangeMappings(after: Record<string, any>, before: Record<string, any>): void;
187
+ onchangeData(after: Record<string, any>, before: Record<string, any>): void;
188
+ buildMappings(): void;
189
+ executeMappings(force?: boolean): void;
190
+ disposeMappings(): void;
191
+ ondropfile(transfered: FileList, files: string[]): void;
192
+ transcoordS2P(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
193
+ transcoordP2S(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
194
+ transcoordS2T(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
195
+ transcoordT2P(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
196
+ transcoordT2S(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
197
+ transcoordS2TR(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
198
+ transcoordS2O(x: number, y: number, target: Component): import("@hatiolab/things-scene").POINT;
199
+ transcoordC2S(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
200
+ transcoordS2C(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
201
+ toParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
202
+ fromParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
203
+ toScene(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
204
+ fromScene(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
205
+ toLocal(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
206
+ toGlobal(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
207
+ toOther(x: number, y: number, target: Component): import("@hatiolab/things-scene").POINT;
208
+ on(name: string | object, callback: Function, context?: any): any;
209
+ off(name?: string | object, callback?: Function, context?: any): any;
210
+ once(name: string | object, callback: Function, context?: any): any;
211
+ trigger(name: string, ...args: any[]): any;
212
+ delegate_on(delegator: any): any;
213
+ delegate_off(delegator: any): any;
214
+ onchange(after: Record<string, any>, before: Record<string, any>): void;
215
+ calculateBounds?(): void;
216
+ oncreate_element?(element: HTMLElement): void;
217
+ removeComponent(component: Component, ghost?: boolean): void;
218
+ addComponent(component: Component, ghost?: boolean): void;
219
+ insertComponentAt(component: Component, index: number, ghost?: boolean): void;
220
+ getOverlay(component: Component): HTMLElement | undefined;
221
+ findById(id: string): Component | undefined;
222
+ findByRefid(ref: string | number): Component | undefined;
223
+ findAllById(id: string): Component[];
224
+ resize(): void;
225
+ fit(type?: string): void;
226
+ get components(): Component[] | undefined;
227
+ get layout(): any;
228
+ get auxOverlay(): HTMLElement | undefined;
229
+ get isReady(): boolean;
230
+ get unitScale(): number;
231
+ get selected(): Component[];
232
+ set selected(_v: Component[]): any;
233
+ get focused(): Component | null;
234
+ set focused(_v: Component | null): any;
235
+ get hasSameParentForAllSelected(): boolean;
236
+ set hasSameParentForAllSelected(_v: boolean): any;
237
+ get fitMode(): string | undefined;
238
+ set fitMode(_v: string | undefined): any;
239
+ get element(): HTMLElement | null;
240
+ set element(_v: HTMLElement | null): any;
241
+ }) & typeof Shape;
242
+ export declare class Carrier extends Carrier_base {
243
+ private _host?;
244
+ private _syncingToHost;
245
+ private _animState?;
246
+ private _animFrameId;
247
+ is3dish(): boolean;
248
+ buildRealObject(): RealObject | undefined;
249
+ get nature(): ComponentNature;
250
+ get hostComponent(): Component | undefined;
251
+ private _getHostTarget;
252
+ private _onHostChanged;
253
+ private _syncToHost;
254
+ private _animateToHost;
255
+ private _animStep;
256
+ private _cancelAnimation;
257
+ private _unbindHost;
258
+ onchange(after: Properties, before: Properties): void;
259
+ ready(): Promise<void>;
260
+ dispose(): void;
261
+ render(ctx: CanvasRenderingContext2D): void;
262
+ }
263
+ export {};
@@ -0,0 +1,272 @@
1
+ import { __decorate } from "tslib";
2
+ /*
3
+ * Copyright © HatioLab Inc. All rights reserved.
4
+ */
5
+ import { RectPath, Shape, sceneComponent, RealObject } from '@hatiolab/things-scene';
6
+ import * as THREE from 'three';
7
+ const NATURE = {
8
+ mutable: false,
9
+ resizable: true,
10
+ rotatable: true,
11
+ properties: [
12
+ {
13
+ type: 'number',
14
+ label: 'shelves',
15
+ name: 'shelves',
16
+ property: 'shelves'
17
+ },
18
+ {
19
+ type: 'color',
20
+ label: 'shelf-color',
21
+ name: 'shelfColor',
22
+ property: 'shelfColor'
23
+ },
24
+ {
25
+ type: 'color',
26
+ label: 'post-color',
27
+ name: 'postColor',
28
+ property: 'postColor'
29
+ },
30
+ {
31
+ type: 'id-input',
32
+ label: 'host',
33
+ name: 'host',
34
+ property: {
35
+ component: true
36
+ }
37
+ }
38
+ ],
39
+ help: 'scene/component/carrier'
40
+ };
41
+ const ANIM_DURATION = 1000;
42
+ const DEFAULT_SHELF_COLOR = '#b0b0b0';
43
+ const DEFAULT_POST_COLOR = '#666666';
44
+ export class Carrier3D extends RealObject {
45
+ build() {
46
+ super.build();
47
+ var { width, height, depth, fillStyle, shelfColor, postColor, shelves = 2 } = this.component.state;
48
+ var w = width;
49
+ var h = height;
50
+ var d = depth || 60;
51
+ var numShelves = Math.max(1, Math.min(shelves, 5));
52
+ var shelfThick = Math.max(1.5, d * 0.04);
53
+ var postR = Math.min(w, h) * 0.03;
54
+ var totalH = d;
55
+ var shelfMat = new THREE.MeshStandardMaterial({
56
+ color: shelfColor || fillStyle || DEFAULT_SHELF_COLOR,
57
+ roughness: 0.4,
58
+ metalness: 0.2
59
+ });
60
+ var postMat = new THREE.MeshStandardMaterial({
61
+ color: postColor || DEFAULT_POST_COLOR,
62
+ roughness: 0.5,
63
+ metalness: 0.3
64
+ });
65
+ // ── 선반판 ──
66
+ for (var i = 0; i < numShelves; i++) {
67
+ var shelfY = (i / (numShelves - 1 || 1)) * (totalH - shelfThick);
68
+ var shelfGeo = new THREE.BoxGeometry(w, shelfThick, h);
69
+ var shelf = new THREE.Mesh(shelfGeo, shelfMat);
70
+ shelf.position.y = shelfY + shelfThick / 2;
71
+ shelf.castShadow = true;
72
+ shelf.receiveShadow = true;
73
+ this.object3d.add(shelf);
74
+ }
75
+ // ── 기둥 4개 (모서리) ──
76
+ var postGeo = new THREE.CylinderGeometry(postR, postR, totalH, 8);
77
+ var insetX = w * 0.42;
78
+ var insetZ = h * 0.42;
79
+ for (var px of [-insetX, insetX]) {
80
+ for (var pz of [-insetZ, insetZ]) {
81
+ var post = new THREE.Mesh(postGeo, postMat);
82
+ post.position.set(px, totalH / 2, pz);
83
+ post.castShadow = true;
84
+ this.object3d.add(post);
85
+ }
86
+ }
87
+ // 수직 중앙 정렬
88
+ this.object3d.children.forEach(child => {
89
+ child.position.y -= totalH / 2;
90
+ });
91
+ }
92
+ }
93
+ /* ── 2D 렌더 ── */
94
+ function renderCarrier(ctx, x, y, w, h, fillStyle, shelfColor, postColor, shelves) {
95
+ var numShelves = Math.max(1, Math.min(shelves || 2, 5));
96
+ var postW = Math.max(2, w * 0.06);
97
+ var inset = postW / 2;
98
+ // ── 기둥 4개 ──
99
+ ctx.fillStyle = postColor || DEFAULT_POST_COLOR;
100
+ for (var px of [x + inset, x + w - inset - postW]) {
101
+ for (var py of [y + inset, y + h - inset - postW]) {
102
+ ctx.fillRect(px, py, postW, postW);
103
+ }
104
+ }
105
+ // ── 선반판 ──
106
+ ctx.fillStyle = shelfColor || fillStyle || DEFAULT_SHELF_COLOR;
107
+ var shelfH = Math.max(2, h * 0.04);
108
+ for (var i = 0; i < numShelves; i++) {
109
+ var sy = y + (i / (numShelves - 1 || 1)) * (h - shelfH);
110
+ ctx.fillRect(x, sy, w, shelfH);
111
+ }
112
+ // 외곽선
113
+ ctx.strokeStyle = '#999999';
114
+ ctx.lineWidth = 1;
115
+ ctx.strokeRect(x, y, w, h);
116
+ }
117
+ let Carrier = class Carrier extends RectPath(Shape) {
118
+ _host;
119
+ _syncingToHost = false;
120
+ _animState;
121
+ _animFrameId = 0;
122
+ is3dish() {
123
+ return true;
124
+ }
125
+ buildRealObject() {
126
+ return new Carrier3D(this);
127
+ }
128
+ get nature() {
129
+ return NATURE;
130
+ }
131
+ get hostComponent() {
132
+ var { host } = this.state;
133
+ if (!this._host && host) {
134
+ this._host = this.root.findById?.(host);
135
+ this._host?.on('change', this._onHostChanged, this);
136
+ }
137
+ return this._host;
138
+ }
139
+ _getHostTarget() {
140
+ var host = this._host;
141
+ if (!host)
142
+ return undefined;
143
+ var hs = host.state;
144
+ var { width, height } = this.state;
145
+ return {
146
+ left: hs.left + (hs.width - width) / 2,
147
+ top: hs.top + (hs.height - height) / 2,
148
+ zPos: (hs.zPos || 0) + (hs.depth || 0),
149
+ rotation: hs.rotation || 0
150
+ };
151
+ }
152
+ _onHostChanged(after) {
153
+ if (after.hasOwnProperty('left') ||
154
+ after.hasOwnProperty('top') ||
155
+ after.hasOwnProperty('zPos') ||
156
+ after.hasOwnProperty('width') ||
157
+ after.hasOwnProperty('height') ||
158
+ after.hasOwnProperty('depth') ||
159
+ after.hasOwnProperty('rotation')) {
160
+ if (this._animState) {
161
+ // 애니메이션 중이면 목표만 갱신
162
+ var target = this._getHostTarget();
163
+ if (target)
164
+ this._animState.to = target;
165
+ }
166
+ else {
167
+ this._syncToHost();
168
+ }
169
+ }
170
+ }
171
+ _syncToHost() {
172
+ var target = this._getHostTarget();
173
+ if (!target)
174
+ return;
175
+ this._syncingToHost = true;
176
+ this.set(target);
177
+ this._syncingToHost = false;
178
+ }
179
+ _animateToHost() {
180
+ var target = this._getHostTarget();
181
+ if (!target)
182
+ return;
183
+ this._cancelAnimation();
184
+ var { left, top, rotation = 0 } = this.state;
185
+ var zPos = this.state.zPos || 0;
186
+ this._animState = {
187
+ startTime: Date.now(),
188
+ from: { left, top, zPos, rotation },
189
+ to: target
190
+ };
191
+ this._animStep();
192
+ }
193
+ _animStep() {
194
+ var anim = this._animState;
195
+ if (!anim)
196
+ return;
197
+ var t = Math.min((Date.now() - anim.startTime) / ANIM_DURATION, 1);
198
+ // easeInOutCubic
199
+ var ease = t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
200
+ this._syncingToHost = true;
201
+ this.set({
202
+ left: anim.from.left + (anim.to.left - anim.from.left) * ease,
203
+ top: anim.from.top + (anim.to.top - anim.from.top) * ease,
204
+ zPos: anim.from.zPos + (anim.to.zPos - anim.from.zPos) * ease,
205
+ rotation: anim.from.rotation + (anim.to.rotation - anim.from.rotation) * ease
206
+ });
207
+ this._syncingToHost = false;
208
+ if (t < 1) {
209
+ this._animFrameId = requestAnimationFrame(() => this._animStep());
210
+ }
211
+ else {
212
+ this._animState = undefined;
213
+ this._animFrameId = 0;
214
+ }
215
+ }
216
+ _cancelAnimation() {
217
+ if (this._animFrameId) {
218
+ cancelAnimationFrame(this._animFrameId);
219
+ this._animFrameId = 0;
220
+ }
221
+ this._animState = undefined;
222
+ }
223
+ _unbindHost() {
224
+ this._cancelAnimation();
225
+ if (this._host) {
226
+ this._host.off('change', this._onHostChanged, this);
227
+ delete this._host;
228
+ }
229
+ }
230
+ onchange(after, before) {
231
+ if (after.hasOwnProperty('host') || before.hasOwnProperty('host')) {
232
+ this._unbindHost();
233
+ // 새 호스트로 애니메이션 전환
234
+ if (this.hostComponent) {
235
+ this._animateToHost();
236
+ }
237
+ }
238
+ // 호스트에 의한 위치 동기화 중이면 재귀 방지
239
+ if (!this._syncingToHost && this._host && !this._animState) {
240
+ if (after.hasOwnProperty('width') ||
241
+ after.hasOwnProperty('height')) {
242
+ this._syncToHost();
243
+ }
244
+ }
245
+ super.onchange(after, before);
246
+ }
247
+ async ready() {
248
+ // 초기 로드 시 즉시 바인딩 (애니메이션 없이)
249
+ if (this.hostComponent) {
250
+ this._syncToHost();
251
+ }
252
+ }
253
+ dispose() {
254
+ this._unbindHost();
255
+ super.dispose();
256
+ }
257
+ render(ctx) {
258
+ var { left, top, width, height } = this.bounds;
259
+ var fillStyle = this.getState('fillStyle');
260
+ var shelfColor = this.getState('shelfColor');
261
+ var postColor = this.getState('postColor');
262
+ var shelves = this.getState('shelves');
263
+ renderCarrier(ctx, left, top, width, height, fillStyle, shelfColor, postColor, shelves);
264
+ ctx.beginPath();
265
+ ctx.rect(left, top, width, height);
266
+ }
267
+ };
268
+ Carrier = __decorate([
269
+ sceneComponent('carrier')
270
+ ], Carrier);
271
+ export { Carrier };
272
+ //# sourceMappingURL=carrier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carrier.js","sourceRoot":"","sources":["../src/carrier.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Component, Properties, ComponentNature, RectPath, Shape, sceneComponent, RealObject } 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 {\n type: 'number',\n label: 'shelves',\n name: 'shelves',\n property: 'shelves'\n },\n {\n type: 'color',\n label: 'shelf-color',\n name: 'shelfColor',\n property: 'shelfColor'\n },\n {\n type: 'color',\n label: 'post-color',\n name: 'postColor',\n property: 'postColor'\n },\n {\n type: 'id-input',\n label: 'host',\n name: 'host',\n property: {\n component: true\n }\n }\n ],\n help: 'scene/component/carrier'\n}\n\nconst ANIM_DURATION = 1000\n\ninterface AnimTarget {\n left: number\n top: number\n zPos: number\n rotation: number\n}\n\ninterface AnimState {\n startTime: number\n from: AnimTarget\n to: AnimTarget\n}\n\nconst DEFAULT_SHELF_COLOR = '#b0b0b0'\nconst DEFAULT_POST_COLOR = '#666666'\n\nexport class Carrier3D extends RealObject {\n build() {\n super.build()\n\n var { width, height, depth, fillStyle, shelfColor, postColor, shelves = 2 } = this.component.state\n\n var w = width\n var h = height\n var d = depth || 60\n var numShelves = Math.max(1, Math.min(shelves, 5))\n\n var shelfThick = Math.max(1.5, d * 0.04)\n var postR = Math.min(w, h) * 0.03\n var totalH = d\n\n var shelfMat = new THREE.MeshStandardMaterial({\n color: shelfColor || fillStyle || DEFAULT_SHELF_COLOR,\n roughness: 0.4,\n metalness: 0.2\n })\n var postMat = new THREE.MeshStandardMaterial({\n color: postColor || DEFAULT_POST_COLOR,\n roughness: 0.5,\n metalness: 0.3\n })\n\n // ── 선반판 ──\n for (var i = 0; i < numShelves; i++) {\n var shelfY = (i / (numShelves - 1 || 1)) * (totalH - shelfThick)\n var shelfGeo = new THREE.BoxGeometry(w, shelfThick, h)\n var shelf = new THREE.Mesh(shelfGeo, shelfMat)\n shelf.position.y = shelfY + shelfThick / 2\n shelf.castShadow = true\n shelf.receiveShadow = true\n this.object3d.add(shelf)\n }\n\n // ── 기둥 4개 (모서리) ──\n var postGeo = new THREE.CylinderGeometry(postR, postR, totalH, 8)\n var insetX = w * 0.42\n var insetZ = h * 0.42\n\n for (var px of [-insetX, insetX]) {\n for (var pz of [-insetZ, insetZ]) {\n var post = new THREE.Mesh(postGeo, postMat)\n post.position.set(px, totalH / 2, pz)\n post.castShadow = true\n this.object3d.add(post)\n }\n }\n\n // 수직 중앙 정렬\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n}\n\n/* ── 2D 렌더 ── */\n\nfunction renderCarrier(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n fillStyle: string,\n shelfColor: string,\n postColor: string,\n shelves: number\n) {\n var numShelves = Math.max(1, Math.min(shelves || 2, 5))\n var postW = Math.max(2, w * 0.06)\n var inset = postW / 2\n\n // ── 기둥 4개 ──\n ctx.fillStyle = postColor || DEFAULT_POST_COLOR\n for (var px of [x + inset, x + w - inset - postW]) {\n for (var py of [y + inset, y + h - inset - postW]) {\n ctx.fillRect(px, py, postW, postW)\n }\n }\n\n // ── 선반판 ──\n ctx.fillStyle = shelfColor || fillStyle || DEFAULT_SHELF_COLOR\n var shelfH = Math.max(2, h * 0.04)\n for (var i = 0; i < numShelves; i++) {\n var sy = y + (i / (numShelves - 1 || 1)) * (h - shelfH)\n ctx.fillRect(x, sy, w, shelfH)\n }\n\n // 외곽선\n ctx.strokeStyle = '#999999'\n ctx.lineWidth = 1\n ctx.strokeRect(x, y, w, h)\n}\n\n@sceneComponent('carrier')\nexport class Carrier extends RectPath(Shape) {\n private _host?: Component\n private _syncingToHost = false\n private _animState?: AnimState\n private _animFrameId = 0\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Carrier3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n get hostComponent(): Component | undefined {\n var { host } = this.state\n\n if (!this._host && host) {\n this._host = this.root.findById?.(host)\n this._host?.on('change', this._onHostChanged, this)\n }\n\n return this._host\n }\n\n private _getHostTarget(): AnimTarget | undefined {\n var host = this._host\n if (!host) return undefined\n\n var hs = host.state\n var { width, height } = this.state\n\n return {\n left: hs.left + (hs.width - width) / 2,\n top: hs.top + (hs.height - height) / 2,\n zPos: (hs.zPos || 0) + (hs.depth || 0),\n rotation: hs.rotation || 0\n }\n }\n\n private _onHostChanged(after: Properties) {\n if (\n after.hasOwnProperty('left') ||\n after.hasOwnProperty('top') ||\n after.hasOwnProperty('zPos') ||\n after.hasOwnProperty('width') ||\n after.hasOwnProperty('height') ||\n after.hasOwnProperty('depth') ||\n after.hasOwnProperty('rotation')\n ) {\n if (this._animState) {\n // 애니메이션 중이면 목표만 갱신\n var target = this._getHostTarget()\n if (target) this._animState.to = target\n } else {\n this._syncToHost()\n }\n }\n }\n\n private _syncToHost() {\n var target = this._getHostTarget()\n if (!target) return\n\n this._syncingToHost = true\n this.set(target)\n this._syncingToHost = false\n }\n\n private _animateToHost() {\n var target = this._getHostTarget()\n if (!target) return\n\n this._cancelAnimation()\n\n var { left, top, rotation = 0 } = this.state\n var zPos = this.state.zPos || 0\n\n this._animState = {\n startTime: Date.now(),\n from: { left, top, zPos, rotation },\n to: target\n }\n\n this._animStep()\n }\n\n private _animStep() {\n var anim = this._animState\n if (!anim) return\n\n var t = Math.min((Date.now() - anim.startTime) / ANIM_DURATION, 1)\n\n // easeInOutCubic\n var ease = t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n this._syncingToHost = true\n this.set({\n left: anim.from.left + (anim.to.left - anim.from.left) * ease,\n top: anim.from.top + (anim.to.top - anim.from.top) * ease,\n zPos: anim.from.zPos + (anim.to.zPos - anim.from.zPos) * ease,\n rotation: anim.from.rotation + (anim.to.rotation - anim.from.rotation) * ease\n })\n this._syncingToHost = false\n\n if (t < 1) {\n this._animFrameId = requestAnimationFrame(() => this._animStep())\n } else {\n this._animState = undefined\n this._animFrameId = 0\n }\n }\n\n private _cancelAnimation() {\n if (this._animFrameId) {\n cancelAnimationFrame(this._animFrameId)\n this._animFrameId = 0\n }\n this._animState = undefined\n }\n\n private _unbindHost() {\n this._cancelAnimation()\n if (this._host) {\n this._host.off('change', this._onHostChanged, this)\n delete this._host\n }\n }\n\n onchange(after: Properties, before: Properties) {\n if (after.hasOwnProperty('host') || before.hasOwnProperty('host')) {\n this._unbindHost()\n // 새 호스트로 애니메이션 전환\n if (this.hostComponent) {\n this._animateToHost()\n }\n }\n\n // 호스트에 의한 위치 동기화 중이면 재귀 방지\n if (!this._syncingToHost && this._host && !this._animState) {\n if (\n after.hasOwnProperty('width') ||\n after.hasOwnProperty('height')\n ) {\n this._syncToHost()\n }\n }\n\n super.onchange(after, before)\n }\n\n async ready() {\n // 초기 로드 시 즉시 바인딩 (애니메이션 없이)\n if (this.hostComponent) {\n this._syncToHost()\n }\n }\n\n dispose() {\n this._unbindHost()\n super.dispose()\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n var fillStyle = this.getState('fillStyle')\n var shelfColor = this.getState('shelfColor')\n var postColor = this.getState('postColor')\n var shelves = this.getState('shelves')\n\n renderCarrier(ctx, left, top, width, height, fillStyle, shelfColor, postColor, shelves)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n}\n"]}