@operato/scene-visualizer 10.0.0-beta.8 → 10.0.0-beta.9
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.
- package/dist/editors/index.d.ts +1 -0
- package/dist/editors/index.js +5 -0
- package/dist/editors/index.js.map +1 -1
- package/dist/editors/property-editor-stocker-location.d.ts +13 -0
- package/dist/editors/property-editor-stocker-location.js +151 -0
- package/dist/editors/property-editor-stocker-location.js.map +1 -0
- package/dist/editors/property-editor-stocker-ports.d.ts +8 -0
- package/dist/editors/property-editor-stocker-ports.js +112 -0
- package/dist/editors/property-editor-stocker-ports.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/stocker-3d.d.ts +23 -0
- package/dist/stocker-3d.js +352 -0
- package/dist/stocker-3d.js.map +1 -0
- package/dist/stocker-port-3d.d.ts +14 -0
- package/dist/stocker-port-3d.js +80 -0
- package/dist/stocker-port-3d.js.map +1 -0
- package/dist/stocker-port.d.ts +254 -0
- package/dist/stocker-port.js +123 -0
- package/dist/stocker-port.js.map +1 -0
- package/dist/stocker.d.ts +340 -0
- package/dist/stocker.js +370 -0
- package/dist/stocker.js.map +1 -0
- package/dist/templates/index.d.ts +40 -0
- package/dist/templates/index.js +5 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/stocker-port.d.ts +17 -0
- package/dist/templates/stocker-port.js +17 -0
- package/dist/templates/stocker-port.js.map +1 -0
- package/dist/templates/stocker.d.ts +27 -0
- package/dist/templates/stocker.js +38 -0
- package/dist/templates/stocker.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { Component, ComponentNature, RealObject, Shape } from '@hatiolab/things-scene';
|
|
2
|
+
interface StockerPortData {
|
|
3
|
+
CARRIER?: string;
|
|
4
|
+
STATUS?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const StockerPort_base: (new (...args: any[]) => {
|
|
7
|
+
contains(x: number, y: number): boolean;
|
|
8
|
+
get path(): {
|
|
9
|
+
x: any;
|
|
10
|
+
y: any;
|
|
11
|
+
}[];
|
|
12
|
+
set path(path: {
|
|
13
|
+
x: any;
|
|
14
|
+
y: any;
|
|
15
|
+
}[]): any;
|
|
16
|
+
get anchors(): {
|
|
17
|
+
name: string;
|
|
18
|
+
position: {
|
|
19
|
+
x: any;
|
|
20
|
+
y: any;
|
|
21
|
+
};
|
|
22
|
+
}[];
|
|
23
|
+
get bounds(): any;
|
|
24
|
+
set bounds(bounds: any): any;
|
|
25
|
+
render(ctx: CanvasRenderingContext2D): void;
|
|
26
|
+
_app: any;
|
|
27
|
+
_model: any;
|
|
28
|
+
_state: any;
|
|
29
|
+
_delta: any;
|
|
30
|
+
_animation: any;
|
|
31
|
+
_animate: any;
|
|
32
|
+
_parent: any;
|
|
33
|
+
_disposed: any;
|
|
34
|
+
_textHidden: any;
|
|
35
|
+
_text_substitutor: any;
|
|
36
|
+
_value_substitutor: any;
|
|
37
|
+
_mappings: any;
|
|
38
|
+
_realObject: import("@hatiolab/things-scene").IRealObject | undefined;
|
|
39
|
+
_cachedState: any;
|
|
40
|
+
updatedAt: any;
|
|
41
|
+
fontSize: any;
|
|
42
|
+
__cache__: any;
|
|
43
|
+
created(): void;
|
|
44
|
+
added(parent: any): void;
|
|
45
|
+
removed(parent: any): void;
|
|
46
|
+
ready(): Promise<void>;
|
|
47
|
+
touch(): void;
|
|
48
|
+
clearCache(...attrs: any[]): void;
|
|
49
|
+
removeSelf(completely: any): void;
|
|
50
|
+
resetAnimation(): void;
|
|
51
|
+
dispose(): void;
|
|
52
|
+
get nature(): import("@hatiolab/things-scene").ComponentNature;
|
|
53
|
+
get disposed(): boolean;
|
|
54
|
+
isLayer(): boolean;
|
|
55
|
+
isGroup(): boolean;
|
|
56
|
+
isContainer(): this is import("@hatiolab/things-scene/dist-types/types/component.js").Container;
|
|
57
|
+
isLine(): boolean;
|
|
58
|
+
isRoot(): boolean;
|
|
59
|
+
isRootModel(): boolean;
|
|
60
|
+
is3dish(): boolean;
|
|
61
|
+
get is3dMode(): boolean;
|
|
62
|
+
isIn3DSpace(): boolean;
|
|
63
|
+
isTemplate(): boolean;
|
|
64
|
+
isHTMLElement(): boolean;
|
|
65
|
+
isConnectable(): boolean;
|
|
66
|
+
isIdentifiable(): boolean;
|
|
67
|
+
isPositionable(): boolean;
|
|
68
|
+
replaceRefids(replaceMap: any): void;
|
|
69
|
+
get(property: any): any;
|
|
70
|
+
set(props: any, propval?: any): any;
|
|
71
|
+
getState(property: any): any;
|
|
72
|
+
setState(props: any, propval?: any): any;
|
|
73
|
+
get model(): any;
|
|
74
|
+
get state(): any;
|
|
75
|
+
get hierarchy(): any;
|
|
76
|
+
get volatile(): never[];
|
|
77
|
+
_applyProps(target: any, props: any, options: any): any;
|
|
78
|
+
move(offset: {
|
|
79
|
+
x: number;
|
|
80
|
+
y: number;
|
|
81
|
+
}, ...args: boolean[]): void;
|
|
82
|
+
symmetryX(x?: number): void;
|
|
83
|
+
symmetryY(y: number): void;
|
|
84
|
+
adjustResize(bounds: import("@hatiolab/things-scene").BOUNDS, origin_bounds: import("@hatiolab/things-scene").BOUNDS, diagonal: boolean): {
|
|
85
|
+
left: any;
|
|
86
|
+
top: any;
|
|
87
|
+
width: any;
|
|
88
|
+
height: any;
|
|
89
|
+
};
|
|
90
|
+
adjustRotation(rotation: number, step: boolean): number;
|
|
91
|
+
outline(progress: number): any;
|
|
92
|
+
get center(): import("@hatiolab/things-scene").POINT;
|
|
93
|
+
set center(p: import("@hatiolab/things-scene").POINT): any;
|
|
94
|
+
get location(): import("@hatiolab/things-scene").POINT;
|
|
95
|
+
set location(l: import("@hatiolab/things-scene").POINT): any;
|
|
96
|
+
get rotate(): import("@hatiolab/things-scene").POINT;
|
|
97
|
+
set rotate(r: import("@hatiolab/things-scene").POINT): any;
|
|
98
|
+
get dimension(): import("@hatiolab/things-scene").DIMENSION;
|
|
99
|
+
set dimension(d: import("@hatiolab/things-scene").DIMENSION): any;
|
|
100
|
+
get drawPath(): import("@hatiolab/things-scene").POINT[];
|
|
101
|
+
get rotatePoint(): import("@hatiolab/things-scene").POINT;
|
|
102
|
+
get mutable(): boolean;
|
|
103
|
+
get resizable(): boolean;
|
|
104
|
+
get rotatable(): boolean;
|
|
105
|
+
buildRealObject(): import("@hatiolab/things-scene").IRealObject | undefined;
|
|
106
|
+
get realObject(): import("@hatiolab/things-scene").IRealObject | undefined;
|
|
107
|
+
draw(context?: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
108
|
+
prerender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
109
|
+
postrender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
110
|
+
prepare(resolve: (component: Component) => void, reject: (reason: any) => void): void;
|
|
111
|
+
prepareIf(condition: boolean): void;
|
|
112
|
+
drawText(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
113
|
+
drawStroke(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
|
|
114
|
+
drawFill(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
|
|
115
|
+
get strokeStyle(): any;
|
|
116
|
+
set strokeStyle(v: any): any;
|
|
117
|
+
get fillStyle(): any;
|
|
118
|
+
set fillStyle(v: any): any;
|
|
119
|
+
get fontColor(): string;
|
|
120
|
+
set fontColor(v: string): any;
|
|
121
|
+
get rotation(): number;
|
|
122
|
+
set rotation(v: number): any;
|
|
123
|
+
get decorators(): string[];
|
|
124
|
+
get decotag(): string;
|
|
125
|
+
get hidden(): boolean;
|
|
126
|
+
set hidden(v: boolean): any;
|
|
127
|
+
get tag(): string;
|
|
128
|
+
set tag(v: string): any;
|
|
129
|
+
get appendum(): any;
|
|
130
|
+
set appendum(v: any): any;
|
|
131
|
+
defaultTextSubstitutor(): string;
|
|
132
|
+
textLines(context?: import("@hatiolab/things-scene").SceneRenderContext): any[][];
|
|
133
|
+
get font(): string;
|
|
134
|
+
get lineHeight(): number;
|
|
135
|
+
get textSubstitutor(): () => string;
|
|
136
|
+
get text(): string;
|
|
137
|
+
set text(v: string): any;
|
|
138
|
+
get textBounds(): import("@hatiolab/things-scene").BOUNDS;
|
|
139
|
+
get textRotation(): number;
|
|
140
|
+
get textHidden(): boolean;
|
|
141
|
+
set textHidden(v: boolean): any;
|
|
142
|
+
get hasTextProperty(): boolean;
|
|
143
|
+
animate(opts: import("@hatiolab/things-scene").AnimationConfig): any;
|
|
144
|
+
effect(context: import("@hatiolab/things-scene").SceneRenderContext, model: any): void;
|
|
145
|
+
serialize(...others: any[]): string;
|
|
146
|
+
trim(): void;
|
|
147
|
+
closeScene(data: any): void;
|
|
148
|
+
delta(attr?: string | object, value?: any): any;
|
|
149
|
+
invalidate(): void;
|
|
150
|
+
get value(): any;
|
|
151
|
+
set value(v: any): any;
|
|
152
|
+
get data(): any;
|
|
153
|
+
set data(v: any): any;
|
|
154
|
+
set tap(v: any): any;
|
|
155
|
+
get mappings(): any[];
|
|
156
|
+
get retention(): number;
|
|
157
|
+
get animation(): import("@hatiolab/things-scene").AnimationController | undefined;
|
|
158
|
+
get started(): boolean;
|
|
159
|
+
set started(v: boolean): any;
|
|
160
|
+
get controls(): import("@hatiolab/things-scene").Control[] | undefined;
|
|
161
|
+
findFirst(finder: string | ((c: Component) => boolean), ...others: any[]): Component | undefined;
|
|
162
|
+
findAll(s: string | ((c: Component) => boolean), ...others: any[]): any[] | undefined;
|
|
163
|
+
capture(x: number, y: number, except?: (c: Component) => boolean): any;
|
|
164
|
+
findAnchor(name: string): any;
|
|
165
|
+
isDescendible(container: Component): boolean;
|
|
166
|
+
getContext(component?: unknown): any;
|
|
167
|
+
get root(): Component;
|
|
168
|
+
get rootModel(): Component;
|
|
169
|
+
get parent(): Component;
|
|
170
|
+
set parent(v: Component): any;
|
|
171
|
+
get scalable(): boolean;
|
|
172
|
+
get stuck(): boolean;
|
|
173
|
+
get capturable(): boolean;
|
|
174
|
+
get position(): string;
|
|
175
|
+
get origin(): string;
|
|
176
|
+
get offset(): import("@hatiolab/things-scene").POINT;
|
|
177
|
+
get app(): import("@hatiolab/things-scene").ApplicationContext;
|
|
178
|
+
drawEffect(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
179
|
+
prepareFill(resolve: Function, reject: Function): void;
|
|
180
|
+
prepareFillIf(condition: boolean): void;
|
|
181
|
+
onchangeFill(after: Record<string, any>, before: Record<string, any>): void;
|
|
182
|
+
drawImage(context: import("@hatiolab/things-scene").SceneRenderContext, image: HTMLImageElement, left: number, top: number, width: number, height: number): void;
|
|
183
|
+
mutateBounds(logic: ((bounds: import("@hatiolab/things-scene").BOUNDS) => import("@hatiolab/things-scene").BOUNDS | void) | null, context?: any): void;
|
|
184
|
+
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;
|
|
185
|
+
access(accessor: string): any;
|
|
186
|
+
substitute(template: string, data: any): string | undefined;
|
|
187
|
+
onchangeMappings(after: Record<string, any>, before: Record<string, any>): void;
|
|
188
|
+
onchangeData(after: Record<string, any>, before: Record<string, any>): void;
|
|
189
|
+
buildMappings(): void;
|
|
190
|
+
executeMappings(force?: boolean): void;
|
|
191
|
+
disposeMappings(): void;
|
|
192
|
+
ondropfile(transfered: FileList, files: string[]): void;
|
|
193
|
+
transcoordS2P(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
194
|
+
transcoordP2S(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
195
|
+
transcoordS2T(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
196
|
+
transcoordT2P(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
197
|
+
transcoordT2S(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
198
|
+
transcoordS2TR(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
199
|
+
transcoordS2O(x: number, y: number, target: Component): import("@hatiolab/things-scene").POINT;
|
|
200
|
+
transcoordC2S(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
201
|
+
transcoordS2C(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
202
|
+
toParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
203
|
+
fromParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
204
|
+
toScene(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
205
|
+
fromScene(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
206
|
+
toLocal(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
207
|
+
toGlobal(x: number, y: number, top?: Component): import("@hatiolab/things-scene").POINT;
|
|
208
|
+
toOther(x: number, y: number, target: Component): import("@hatiolab/things-scene").POINT;
|
|
209
|
+
on(name: string | object, callback: Function, context?: any): any;
|
|
210
|
+
off(name?: string | object, callback?: Function, context?: any): any;
|
|
211
|
+
once(name: string | object, callback: Function, context?: any): any;
|
|
212
|
+
trigger(name: string, ...args: any[]): any;
|
|
213
|
+
delegate_on(delegator: any): any;
|
|
214
|
+
delegate_off(delegator: any): any;
|
|
215
|
+
onchange(after: Record<string, any>, before: Record<string, any>): void;
|
|
216
|
+
calculateBounds?(): void;
|
|
217
|
+
oncreate_element?(element: HTMLElement): void;
|
|
218
|
+
removeComponent(component: Component, ghost?: boolean): void;
|
|
219
|
+
addComponent(component: Component, ghost?: boolean): void;
|
|
220
|
+
insertComponentAt(component: Component, index: number, ghost?: boolean): void;
|
|
221
|
+
getOverlay(component: Component): HTMLElement | undefined;
|
|
222
|
+
findById(id: string): Component | undefined;
|
|
223
|
+
findByRefid(ref: string | number): Component | undefined;
|
|
224
|
+
findAllById(id: string): Component[];
|
|
225
|
+
resize(): void;
|
|
226
|
+
fit(type?: string): void;
|
|
227
|
+
get components(): Component[] | undefined;
|
|
228
|
+
get layout(): any;
|
|
229
|
+
get auxOverlay(): HTMLElement | undefined;
|
|
230
|
+
get isReady(): boolean;
|
|
231
|
+
get unitScale(): number;
|
|
232
|
+
get selected(): Component[];
|
|
233
|
+
set selected(_v: Component[]): any;
|
|
234
|
+
get focused(): Component | null;
|
|
235
|
+
set focused(_v: Component | null): any;
|
|
236
|
+
get hasSameParentForAllSelected(): boolean;
|
|
237
|
+
set hasSameParentForAllSelected(_v: boolean): any;
|
|
238
|
+
get fitMode(): string | undefined;
|
|
239
|
+
set fitMode(_v: string | undefined): any;
|
|
240
|
+
get element(): HTMLElement | null;
|
|
241
|
+
set element(_v: HTMLElement | null): any;
|
|
242
|
+
}) & typeof Shape;
|
|
243
|
+
export declare class StockerPort extends StockerPort_base {
|
|
244
|
+
get nature(): ComponentNature;
|
|
245
|
+
is3dish(): boolean;
|
|
246
|
+
buildRealObject(): RealObject | undefined;
|
|
247
|
+
get portType(): 'in' | 'out';
|
|
248
|
+
get targetStockerId(): string | undefined;
|
|
249
|
+
get targetStocker(): Component | undefined;
|
|
250
|
+
get portData(): StockerPortData;
|
|
251
|
+
get hasCarrier(): boolean;
|
|
252
|
+
render(ctx: CanvasRenderingContext2D): void;
|
|
253
|
+
}
|
|
254
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* StockerPort — Stocker의 입출고 포트.
|
|
5
|
+
*
|
|
6
|
+
* 독립 컴포넌트로 모델러에서 자유 배치.
|
|
7
|
+
* targetStocker 속성으로 연결 대상 stocker 지정.
|
|
8
|
+
*/
|
|
9
|
+
import { __decorate } from "tslib";
|
|
10
|
+
import { RectPath, Shape, sceneComponent } from '@hatiolab/things-scene';
|
|
11
|
+
import { StockerPort3d } from './stocker-port-3d.js';
|
|
12
|
+
const NATURE = {
|
|
13
|
+
mutable: false,
|
|
14
|
+
resizable: true,
|
|
15
|
+
rotatable: true,
|
|
16
|
+
properties: [
|
|
17
|
+
{
|
|
18
|
+
type: 'select',
|
|
19
|
+
label: 'port-type',
|
|
20
|
+
name: 'portType',
|
|
21
|
+
property: {
|
|
22
|
+
options: [
|
|
23
|
+
{ display: 'IN', value: 'in' },
|
|
24
|
+
{ display: 'OUT', value: 'out' }
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'id-input',
|
|
30
|
+
label: 'target-stocker',
|
|
31
|
+
name: 'targetStocker',
|
|
32
|
+
property: {
|
|
33
|
+
component: 'stocker'
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'number',
|
|
38
|
+
label: 'depth',
|
|
39
|
+
name: 'depth',
|
|
40
|
+
property: { min: 1 }
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
help: 'scene/component/stocker-port'
|
|
44
|
+
};
|
|
45
|
+
const COLORS = {
|
|
46
|
+
in: '#27ae60',
|
|
47
|
+
out: '#e67e22',
|
|
48
|
+
empty: '#ddd',
|
|
49
|
+
stroke: '#666',
|
|
50
|
+
carrier: '#4a9eff'
|
|
51
|
+
};
|
|
52
|
+
let StockerPort = class StockerPort extends RectPath(Shape) {
|
|
53
|
+
get nature() { return NATURE; }
|
|
54
|
+
is3dish() { return true; }
|
|
55
|
+
buildRealObject() {
|
|
56
|
+
return new StockerPort3d(this);
|
|
57
|
+
}
|
|
58
|
+
get portType() {
|
|
59
|
+
return this.getState('portType') || 'in';
|
|
60
|
+
}
|
|
61
|
+
get targetStockerId() {
|
|
62
|
+
return this.getState('targetStocker');
|
|
63
|
+
}
|
|
64
|
+
get targetStocker() {
|
|
65
|
+
const id = this.targetStockerId;
|
|
66
|
+
if (!id)
|
|
67
|
+
return undefined;
|
|
68
|
+
return this.root?.findById?.(id);
|
|
69
|
+
}
|
|
70
|
+
get portData() {
|
|
71
|
+
return (this.data || {});
|
|
72
|
+
}
|
|
73
|
+
get hasCarrier() {
|
|
74
|
+
return !!this.portData.CARRIER;
|
|
75
|
+
}
|
|
76
|
+
// ── 2D Rendering ──
|
|
77
|
+
render(ctx) {
|
|
78
|
+
const { left, top, width, height } = this.bounds;
|
|
79
|
+
const isIn = this.portType === 'in';
|
|
80
|
+
const hasCarrier = this.hasCarrier;
|
|
81
|
+
// 배경
|
|
82
|
+
ctx.beginPath();
|
|
83
|
+
ctx.rect(left, top, width, height);
|
|
84
|
+
ctx.fillStyle = hasCarrier ? COLORS.carrier : COLORS.empty;
|
|
85
|
+
ctx.fill();
|
|
86
|
+
// 테두리
|
|
87
|
+
ctx.strokeStyle = isIn ? COLORS.in : COLORS.out;
|
|
88
|
+
ctx.lineWidth = 2;
|
|
89
|
+
ctx.stroke();
|
|
90
|
+
// 방향 표시 (화살표)
|
|
91
|
+
const cx = left + width / 2;
|
|
92
|
+
const cy = top + height / 2;
|
|
93
|
+
const arrowSize = Math.min(width, height) * 0.3;
|
|
94
|
+
ctx.fillStyle = isIn ? COLORS.in : COLORS.out;
|
|
95
|
+
ctx.beginPath();
|
|
96
|
+
if (isIn) {
|
|
97
|
+
// 아래 방향 화살표 (IN)
|
|
98
|
+
ctx.moveTo(cx, cy + arrowSize);
|
|
99
|
+
ctx.lineTo(cx - arrowSize * 0.6, cy - arrowSize * 0.3);
|
|
100
|
+
ctx.lineTo(cx + arrowSize * 0.6, cy - arrowSize * 0.3);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// 위 방향 화살표 (OUT)
|
|
104
|
+
ctx.moveTo(cx, cy - arrowSize);
|
|
105
|
+
ctx.lineTo(cx - arrowSize * 0.6, cy + arrowSize * 0.3);
|
|
106
|
+
ctx.lineTo(cx + arrowSize * 0.6, cy + arrowSize * 0.3);
|
|
107
|
+
}
|
|
108
|
+
ctx.closePath();
|
|
109
|
+
ctx.fill();
|
|
110
|
+
// 라벨
|
|
111
|
+
const label = this.state.id || (isIn ? 'IN' : 'OUT');
|
|
112
|
+
ctx.fillStyle = '#333';
|
|
113
|
+
ctx.font = `${Math.min(width * 0.25, height * 0.25, 11)}px sans-serif`;
|
|
114
|
+
ctx.textAlign = 'center';
|
|
115
|
+
ctx.textBaseline = 'bottom';
|
|
116
|
+
ctx.fillText(label, cx, top + height - 2);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
StockerPort = __decorate([
|
|
120
|
+
sceneComponent('stocker-port')
|
|
121
|
+
], StockerPort);
|
|
122
|
+
export { StockerPort };
|
|
123
|
+
//# sourceMappingURL=stocker-port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stocker-port.js","sourceRoot":"","sources":["../src/stocker-port.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;;AAEH,OAAO,EAA0C,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEpD,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,WAAW;YAClB,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC9B,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;iBACjC;aACF;SACF;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE;gBACR,SAAS,EAAE,SAAS;aACrB;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;SACrB;KACF;IACD,IAAI,EAAE,8BAA8B;CACrC,CAAA;AAED,MAAM,MAAM,GAAG;IACb,EAAE,EAAE,SAAS;IACb,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,SAAS;CACnB,CAAA;AAQM,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,QAAQ,CAAC,KAAK,CAAC;IAE9C,IAAI,MAAM,KAAK,OAAO,MAAM,CAAA,CAAC,CAAC;IAE9B,OAAO,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;IAEzB,eAAe;QACb,OAAO,IAAI,aAAa,CAAC,IAAW,CAAC,CAAA;IACvC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAA;IAC1C,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA;IACvC,CAAC;IAED,IAAI,aAAa;QACf,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAA;QAC/B,IAAI,CAAC,EAAE;YAAE,OAAO,SAAS,CAAA;QACzB,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAoB,CAAA;IAC7C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAA;IAChC,CAAC;IAED,qBAAqB;IAErB,MAAM,CAAC,GAA6B;QAClC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QAElC,KAAK;QACL,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAClC,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;QAC1D,GAAG,CAAC,IAAI,EAAE,CAAA;QAEV,MAAM;QACN,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;QAC/C,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,MAAM,EAAE,CAAA;QAEZ,cAAc;QACd,MAAM,EAAE,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,CAAA;QAC3B,MAAM,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,CAAA;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAA;QAE/C,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;QAC7C,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,IAAI,IAAI,EAAE,CAAC;YACT,iBAAiB;YACjB,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC,CAAA;YAC9B,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,GAAG,GAAG,EAAE,EAAE,GAAG,SAAS,GAAG,GAAG,CAAC,CAAA;YACtD,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,GAAG,GAAG,EAAE,EAAE,GAAG,SAAS,GAAG,GAAG,CAAC,CAAA;QACxD,CAAC;aAAM,CAAC;YACN,iBAAiB;YACjB,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC,CAAA;YAC9B,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,GAAG,GAAG,EAAE,EAAE,GAAG,SAAS,GAAG,GAAG,CAAC,CAAA;YACtD,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,GAAG,GAAG,EAAE,EAAE,GAAG,SAAS,GAAG,GAAG,CAAC,CAAA;QACxD,CAAC;QACD,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,EAAE,CAAA;QAEV,KAAK;QACL,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACpD,GAAG,CAAC,SAAS,GAAG,MAAM,CAAA;QACtB,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC,eAAe,CAAA;QACtE,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAA;QACxB,GAAG,CAAC,YAAY,GAAG,QAAQ,CAAA;QAC3B,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;IAC3C,CAAC;CACF,CAAA;AA/EY,WAAW;IADvB,cAAc,CAAC,cAAc,CAAC;GAClB,WAAW,CA+EvB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * StockerPort — Stocker의 입출고 포트.\n *\n * 독립 컴포넌트로 모델러에서 자유 배치.\n * targetStocker 속성으로 연결 대상 stocker 지정.\n */\n\nimport { Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\nimport { StockerPort3d } from './stocker-port-3d.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'port-type',\n name: 'portType',\n property: {\n options: [\n { display: 'IN', value: 'in' },\n { display: 'OUT', value: 'out' }\n ]\n }\n },\n {\n type: 'id-input',\n label: 'target-stocker',\n name: 'targetStocker',\n property: {\n component: 'stocker'\n }\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth',\n property: { min: 1 }\n }\n ],\n help: 'scene/component/stocker-port'\n}\n\nconst COLORS = {\n in: '#27ae60',\n out: '#e67e22',\n empty: '#ddd',\n stroke: '#666',\n carrier: '#4a9eff'\n}\n\ninterface StockerPortData {\n CARRIER?: string\n STATUS?: string\n}\n\n@sceneComponent('stocker-port')\nexport class StockerPort extends RectPath(Shape) {\n\n get nature() { return NATURE }\n\n is3dish() { return true }\n\n buildRealObject(): RealObject | undefined {\n return new StockerPort3d(this as any)\n }\n\n get portType(): 'in' | 'out' {\n return this.getState('portType') || 'in'\n }\n\n get targetStockerId(): string | undefined {\n return this.getState('targetStocker')\n }\n\n get targetStocker(): Component | undefined {\n const id = this.targetStockerId\n if (!id) return undefined\n return this.root?.findById?.(id)\n }\n\n get portData(): StockerPortData {\n return (this.data || {}) as StockerPortData\n }\n\n get hasCarrier(): boolean {\n return !!this.portData.CARRIER\n }\n\n // ── 2D Rendering ──\n\n render(ctx: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n const isIn = this.portType === 'in'\n const hasCarrier = this.hasCarrier\n\n // 배경\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n ctx.fillStyle = hasCarrier ? COLORS.carrier : COLORS.empty\n ctx.fill()\n\n // 테두리\n ctx.strokeStyle = isIn ? COLORS.in : COLORS.out\n ctx.lineWidth = 2\n ctx.stroke()\n\n // 방향 표시 (화살표)\n const cx = left + width / 2\n const cy = top + height / 2\n const arrowSize = Math.min(width, height) * 0.3\n\n ctx.fillStyle = isIn ? COLORS.in : COLORS.out\n ctx.beginPath()\n if (isIn) {\n // 아래 방향 화살표 (IN)\n ctx.moveTo(cx, cy + arrowSize)\n ctx.lineTo(cx - arrowSize * 0.6, cy - arrowSize * 0.3)\n ctx.lineTo(cx + arrowSize * 0.6, cy - arrowSize * 0.3)\n } else {\n // 위 방향 화살표 (OUT)\n ctx.moveTo(cx, cy - arrowSize)\n ctx.lineTo(cx - arrowSize * 0.6, cy + arrowSize * 0.3)\n ctx.lineTo(cx + arrowSize * 0.6, cy + arrowSize * 0.3)\n }\n ctx.closePath()\n ctx.fill()\n\n // 라벨\n const label = this.state.id || (isIn ? 'IN' : 'OUT')\n ctx.fillStyle = '#333'\n ctx.font = `${Math.min(width * 0.25, height * 0.25, 11)}px sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'bottom'\n ctx.fillText(label, cx, top + height - 2)\n }\n}\n"]}
|