@operato/scene-visualizer 10.0.0-beta.10 → 10.0.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -242,7 +242,6 @@ declare const StockerPort_base: (new (...args: any[]) => {
242
242
  }) & typeof Shape;
243
243
  export declare class StockerPort extends StockerPort_base {
244
244
  get nature(): ComponentNature;
245
- is3dish(): boolean;
246
245
  buildRealObject(): RealObject | undefined;
247
246
  get portType(): 'in' | 'out';
248
247
  get targetStockerId(): string | undefined;
@@ -51,7 +51,6 @@ const COLORS = {
51
51
  };
52
52
  let StockerPort = class StockerPort extends RectPath(Shape) {
53
53
  get nature() { return NATURE; }
54
- is3dish() { return true; }
55
54
  buildRealObject() {
56
55
  return new StockerPort3d(this);
57
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stocker-port.js","sourceRoot":"","sources":["../src/stocker-port.ts"],"names":[],"mappings":"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","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"]}
1
+ {"version":3,"file":"stocker-port.js","sourceRoot":"","sources":["../src/stocker-port.ts"],"names":[],"mappings":"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","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\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"]}
package/dist/stocker.d.ts CHANGED
@@ -321,7 +321,6 @@ export declare class Stocker extends Stocker_base {
321
321
  private _parsedCells;
322
322
  private _parsedCranes;
323
323
  get nature(): ComponentNature;
324
- is3dish(): boolean;
325
324
  buildRealObject(): RealObject | undefined;
326
325
  get layout(): StockerLayout;
327
326
  get locationRule(): LocationRule;
package/dist/stocker.js CHANGED
@@ -175,7 +175,6 @@ let Stocker = class Stocker extends RectPath(Shape) {
175
175
  _parsedCells = [];
176
176
  _parsedCranes = [];
177
177
  get nature() { return NATURE; }
178
- is3dish() { return true; }
179
178
  buildRealObject() {
180
179
  return new Stocker3d(this);
181
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stocker.js","sourceRoot":"","sources":["../src/stocker.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Stocker (AS/RS) Component\n *\n * Configurable automated storage/retrieval system:\n * - Independent L/R rack configuration (bays, levels, depth)\n * - Freely positioned In/Out ports\n * - Central aisle with crane (2-axis movement)\n */\n\nimport { Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\nimport { Stocker3d } from './stocker-3d.js'\n\n// ── Types ──\n\nexport interface RackConfig {\n bays: number\n levels: number\n depthCount: number\n}\n\nexport interface LocationRule {\n pattern: string // '{side}{bay}-{level}-{depth}'\n sideLabels: { L: string; R: string } // { L: 'A', R: 'B' }\n bayDir: 'ltr' | 'rtl' // 번호 방향\n levelDir: 'btt' | 'ttb' // 번호 방향 (bottom-to-top / top-to-bottom)\n bayStart: number // 시작 번호\n levelStart: number\n depthStart: number\n bayDigits: number // 자릿수 (0=패딩 없음)\n levelDigits: number\n depthDigits: number\n}\n\nexport interface CraneData {\n id?: string\n bay: number\n level: number\n side?: 'L' | 'R'\n status?: string // IDLE, MOVING, PICKING, PLACING\n carrier?: string\n}\n\nexport interface StockerCell {\n side: 'L' | 'R'\n bay: number\n level: number\n depth: number\n carrier?: string\n status?: string // FULL, EMPTY, RESERVED, ERROR, ...\n}\n\nexport interface StockerData {\n STATUS?: string\n // 단일 crane (하위 호환)\n CRANE_BAY?: number\n CRANE_LEVEL?: number\n CRANE_SIDE?: 'L' | 'R'\n CRANE_STATUS?: string\n CRANE_CARRIER?: string\n // 복수 crane\n CRANES?: string | CraneData[]\n CELLS?: string | StockerCell[]\n TOTAL_CAPACITY?: number\n CURRENT_COUNT?: number\n}\n\n// ── Layout ──\n\nexport type FrontSide = 'auto' | 'top' | 'bottom' | 'left' | 'right'\n\nexport interface RackLayout {\n x: number; y: number; w: number; h: number\n config: RackConfig\n}\n\nexport interface StockerLayout {\n width: number\n height: number\n left: number\n top: number\n vertical: boolean\n flipped: boolean\n along: number\n across: number\n leftRack: RackLayout | null\n rightRack: RackLayout | null\n aisle: { x: number; y: number; w: number; h: number }\n maxBays: number\n bayW: number\n}\n\nexport function computeLayout(state: any): StockerLayout {\n const { left = 0, top = 0, width = 200, height = 100, aisleRatio = 0.15 } = state\n const frontSide: FrontSide = state.frontSide || 'auto'\n\n let vertical: boolean\n let flipped: boolean\n\n switch (frontSide) {\n case 'left': vertical = false; flipped = false; break\n case 'right': vertical = false; flipped = true; break\n case 'top': vertical = true; flipped = false; break\n case 'bottom': vertical = true; flipped = true; break\n default: vertical = height > width; flipped = false; break\n }\n\n const along = vertical ? height : width\n const across = vertical ? width : height\n\n const lRack = parseRackConfig(state, 'l')\n const rRack = parseRackConfig(state, 'r')\n const hasLeft = lRack.bays > 0 && lRack.levels > 0\n const hasRight = rRack.bays > 0 && rRack.levels > 0\n const hasBoth = hasLeft && hasRight\n\n const maxBays = Math.max(lRack.bays || 0, rRack.bays || 0, 1)\n const bayW = along / maxBays\n\n const aisleSize = across * aisleRatio\n const rackAreaSize = across - aisleSize\n\n let leftLayout: RackLayout | null = null\n let rightLayout: RackLayout | null = null\n\n if (vertical) {\n if (hasBoth) {\n const rackW = rackAreaSize / 2\n leftLayout = { x: left, y: top, w: rackW, h: height, config: lRack }\n rightLayout = { x: left + rackW + aisleSize, y: top, w: rackW, h: height, config: rRack }\n } else if (hasLeft) {\n leftLayout = { x: left, y: top, w: rackAreaSize, h: height, config: lRack }\n } else if (hasRight) {\n rightLayout = { x: left + aisleSize, y: top, w: rackAreaSize, h: height, config: rRack }\n }\n const aisleX = leftLayout ? leftLayout.x + leftLayout.w : left\n const aisle = { x: aisleX, y: top, w: aisleSize, h: height }\n return { width, height, left, top, vertical, flipped, along, across, leftRack: leftLayout, rightRack: rightLayout, aisle, maxBays, bayW }\n } else {\n if (hasBoth) {\n const rackH = rackAreaSize / 2\n leftLayout = { x: left, y: top, w: width, h: rackH, config: lRack }\n rightLayout = { x: left, y: top + rackH + aisleSize, w: width, h: rackH, config: rRack }\n } else if (hasLeft) {\n leftLayout = { x: left, y: top, w: width, h: rackAreaSize, config: lRack }\n } else if (hasRight) {\n rightLayout = { x: left, y: top + aisleSize, w: width, h: rackAreaSize, config: rRack }\n }\n const aisleY = leftLayout ? leftLayout.y + leftLayout.h : top\n const aisle = { x: left, y: aisleY, w: width, h: aisleSize }\n return { width, height, left, top, vertical, flipped, along, across, leftRack: leftLayout, rightRack: rightLayout, aisle, maxBays, bayW }\n }\n}\n\nexport function parseRackConfig(state: any, prefix: 'l' | 'r'): RackConfig {\n return {\n bays: state[`${prefix}Bays`] ?? 10,\n levels: state[`${prefix}Levels`] ?? 5,\n depthCount: state[`${prefix}Depth`] ?? 1\n }\n}\n\n// ── Location ──\n\nexport const DEFAULT_LOCATION_RULE: LocationRule = {\n pattern: '{side}{bay}-{level}-{depth}',\n sideLabels: { L: 'L', R: 'R' },\n bayDir: 'ltr', levelDir: 'btt',\n bayStart: 1, levelStart: 1, depthStart: 1,\n bayDigits: 2, levelDigits: 2, depthDigits: 0\n}\n\nexport function parseLocationRule(state: any): LocationRule {\n const raw = state.locationRule\n if (!raw) return DEFAULT_LOCATION_RULE\n if (typeof raw === 'string') {\n try { return { ...DEFAULT_LOCATION_RULE, ...JSON.parse(raw) } } catch { return DEFAULT_LOCATION_RULE }\n }\n return { ...DEFAULT_LOCATION_RULE, ...raw }\n}\n\nfunction padNum(n: number, digits: number): string {\n if (digits <= 0) return String(n)\n return String(n).padStart(digits, '0')\n}\n\nexport function buildLocationId(\n rule: LocationRule, side: 'L' | 'R', bay: number, level: number, depth: number, rackConfig: RackConfig\n): string {\n const sideLabel = rule.sideLabels[side] || side\n const bayNum = rule.bayDir === 'rtl' ? rackConfig.bays - bay + rule.bayStart : bay - 1 + rule.bayStart\n const levelNum = rule.levelDir === 'ttb' ? rackConfig.levels - level + rule.levelStart : level - 1 + rule.levelStart\n const depthNum = depth - 1 + rule.depthStart\n return rule.pattern\n .replace(/{side}/gi, sideLabel)\n .replace(/{bay}/gi, padNum(bayNum, rule.bayDigits))\n .replace(/{level}/gi, padNum(levelNum, rule.levelDigits))\n .replace(/{depth}/gi, padNum(depthNum, rule.depthDigits))\n}\n\n// ── NATURE ──\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n { type: 'number', label: 'L-bays', name: 'lBays', property: { min: 0, max: 100, step: 1 } },\n { type: 'number', label: 'L-levels', name: 'lLevels', property: { min: 0, max: 20, step: 1 } },\n { type: 'number', label: 'L-depth', name: 'lDepth', property: { min: 1, max: 3, step: 1 } },\n { type: 'number', label: 'R-bays', name: 'rBays', property: { min: 0, max: 100, step: 1 } },\n { type: 'number', label: 'R-levels', name: 'rLevels', property: { min: 0, max: 20, step: 1 } },\n { type: 'number', label: 'R-depth', name: 'rDepth', property: { min: 1, max: 3, step: 1 } },\n { type: 'number', label: 'cranes', name: 'cranes', property: { min: 1, max: 4, step: 1 } },\n {\n type: 'select', label: 'front-side', name: 'frontSide',\n property: { options: [\n { display: 'Auto', value: 'auto' }, { display: 'Top', value: 'top' },\n { display: 'Bottom', value: 'bottom' }, { display: 'Left', value: 'left' },\n { display: 'Right', value: 'right' }\n ] }\n },\n { type: 'checkbox', label: 'hide-rack-frame', name: 'hideRackFrame' },\n { type: 'number', label: 'aisle-ratio', name: 'aisleRatio', property: { min: 0.05, max: 0.4, step: 0.01 } },\n { type: 'stocker-location', label: 'location-rule', name: 'locationRule' },\n { type: 'number', label: '3d-height', name: 'depth', property: { min: 1 } }\n ],\n help: 'scene/component/stocker'\n}\n\n// ── Colors ──\n\nconst COLORS = {\n rack: '#e0e0e0',\n rackStroke: '#999',\n aisle: '#d4d4c8',\n aisleRail: '#888',\n crane: '#ff6600',\n craneMast: '#cc5500',\n cellEmpty: '#f5f5f5',\n cellFull: '#4a9eff',\n cellReserved: '#ffcc00',\n cellError: '#e74c3c',\n}\n\n// ── Component ──\n\n@sceneComponent('stocker')\nexport class Stocker extends RectPath(Shape) {\n private _parsedCells: StockerCell[] = []\n private _parsedCranes: CraneData[] = []\n\n get nature() { return NATURE }\n\n is3dish() { return true }\n\n buildRealObject(): RealObject | undefined {\n return new Stocker3d(this as any)\n }\n\n get layout(): StockerLayout {\n return computeLayout(this.state)\n }\n\n get locationRule(): LocationRule {\n return parseLocationRule(this.state)\n }\n\n get cells(): StockerCell[] {\n return this._parsedCells\n }\n\n get cranesData(): CraneData[] {\n return this._parsedCranes\n }\n\n getCellStatus(side: 'L' | 'R', bay: number, level: number, depth: number): string | undefined {\n return this._parsedCells.find(\n c => c.side === side && c.bay === bay && c.level === level && c.depth === depth\n )?.status\n }\n\n getLocationId(side: 'L' | 'R', bay: number, level: number, depth: number): string {\n const rackConfig = parseRackConfig(this.state, side === 'L' ? 'l' : 'r')\n return buildLocationId(this.locationRule, side, bay, level, depth, rackConfig)\n }\n\n // ── Data parsing ──\n\n onchangeData(_after: any, _before: any) {\n const data = (this.data || {}) as StockerData\n\n if (typeof data.CELLS === 'string') {\n try { this._parsedCells = JSON.parse(data.CELLS) } catch { this._parsedCells = [] }\n } else if (Array.isArray(data.CELLS)) {\n this._parsedCells = data.CELLS\n }\n\n if (data.CRANES) {\n if (typeof data.CRANES === 'string') {\n try {\n const parsed = JSON.parse(data.CRANES)\n this._parsedCranes = Array.isArray(parsed) ? parsed : []\n } catch { this._parsedCranes = [] }\n } else if (Array.isArray(data.CRANES)) {\n this._parsedCranes = data.CRANES\n }\n } else if (data.CRANE_BAY != null) {\n this._parsedCranes = [{\n id: 'CR1', bay: data.CRANE_BAY, level: data.CRANE_LEVEL ?? 1,\n side: data.CRANE_SIDE, status: data.CRANE_STATUS, carrier: data.CRANE_CARRIER\n }]\n }\n\n this.invalidate()\n }\n\n // ── 2D Rendering (top view) ──\n\n render(ctx: CanvasRenderingContext2D) {\n const { left = 0, top = 0, width = 200, height = 100 } = this.state\n const layout = this.layout\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n\n if (layout.leftRack) this._drawRack(ctx, layout.leftRack, 'L', layout)\n if (layout.rightRack) this._drawRack(ctx, layout.rightRack, 'R', layout)\n\n this._drawAisle(ctx, layout)\n this._drawCranes(ctx, layout)\n }\n\n private _visualBay(layout: StockerLayout, bay: number): number {\n return layout.flipped ? layout.maxBays - bay + 1 : bay\n }\n\n private _drawRack(ctx: CanvasRenderingContext2D, rack: RackLayout, side: 'L' | 'R', layout: StockerLayout) {\n const { bays, levels, depthCount } = rack.config\n const { vertical, bayW } = layout\n const depthCellSize = vertical ? rack.w / depthCount : rack.h / depthCount\n\n ctx.strokeStyle = COLORS.rackStroke\n ctx.lineWidth = 0.5\n\n for (let d = 0; d < depthCount; d++) {\n for (let b = 1; b <= bays; b++) {\n const vb = this._visualBay(layout, b)\n\n let cx: number, cy: number, cw: number, ch: number\n if (vertical) {\n cx = rack.x + d * depthCellSize\n cy = rack.y + (vb - 1) * bayW\n cw = depthCellSize\n ch = bayW\n } else {\n cx = rack.x + (vb - 1) * bayW\n cy = rack.y + d * depthCellSize\n cw = bayW\n ch = depthCellSize\n }\n\n let occupied = 0\n for (let l = 1; l <= levels; l++) {\n const s = this.getCellStatus(side, b, l, d + 1)\n if (s === 'FULL' || s === 'RESERVED') occupied++\n }\n\n const ratio = levels > 0 ? occupied / levels : 0\n ctx.fillStyle = ratio > 0\n ? this._blendColor(COLORS.cellEmpty, COLORS.cellFull, ratio)\n : COLORS.cellEmpty\n ctx.fillRect(cx, cy, cw, ch)\n ctx.strokeRect(cx, cy, cw, ch)\n }\n }\n }\n\n private _drawAisle(ctx: CanvasRenderingContext2D, layout: StockerLayout) {\n const { aisle, vertical } = layout\n\n ctx.fillStyle = COLORS.aisle\n ctx.fillRect(aisle.x, aisle.y, aisle.w, aisle.h)\n\n ctx.strokeStyle = COLORS.aisleRail\n ctx.lineWidth = 2\n ctx.beginPath()\n\n if (vertical) {\n const railX = aisle.x + aisle.w / 2\n ctx.moveTo(railX, aisle.y)\n ctx.lineTo(railX, aisle.y + aisle.h)\n } else {\n const railY = aisle.y + aisle.h / 2\n ctx.moveTo(aisle.x, railY)\n ctx.lineTo(aisle.x + aisle.w, railY)\n }\n ctx.stroke()\n }\n\n private _drawCranes(ctx: CanvasRenderingContext2D, layout: StockerLayout) {\n const { cranes: craneCount = 1 } = this.state\n const cranesData = this._parsedCranes\n const { aisle, maxBays, bayW, vertical } = layout\n\n const count = Math.max(cranesData.length, craneCount)\n const aisleShort = vertical ? aisle.w : aisle.h\n const craneSize = Math.min(bayW, aisleShort) * 0.6\n\n for (let i = 0; i < count; i++) {\n const cd = cranesData[i]\n const bay = cd?.bay ?? Math.round((i + 1) * maxBays / (count + 1))\n const vb = this._visualBay(layout, bay)\n\n let cx: number, cy: number\n if (vertical) {\n cx = aisle.x + aisle.w / 2\n cy = aisle.y + (vb - 0.5) * bayW\n } else {\n cx = aisle.x + (vb - 0.5) * bayW\n cy = aisle.y + aisle.h / 2\n }\n\n ctx.strokeStyle = COLORS.craneMast\n ctx.lineWidth = 2\n ctx.beginPath()\n if (vertical) {\n ctx.moveTo(aisle.x, cy)\n ctx.lineTo(aisle.x + aisle.w, cy)\n } else {\n ctx.moveTo(cx, aisle.y)\n ctx.lineTo(cx, aisle.y + aisle.h)\n }\n ctx.stroke()\n\n ctx.fillStyle = COLORS.crane\n ctx.fillRect(cx - craneSize / 2, cy - craneSize / 2, craneSize, craneSize)\n\n const label = cd?.id || `CR${i + 1}`\n ctx.fillStyle = '#fff'\n ctx.font = `${Math.max(craneSize * 0.4, 6)}px sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(label, cx, cy)\n }\n }\n\n private _blendColor(c1: string, c2: string, t: number): string {\n const parse = (c: string) => {\n const m = c.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)\n return m ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)] : [200, 200, 200]\n }\n const [r1, g1, b1] = parse(c1)\n const [r2, g2, b2] = parse(c2)\n const r = Math.round(r1 + (r2 - r1) * t)\n const g = Math.round(g1 + (g2 - g1) * t)\n const b = Math.round(b1 + (b2 - b1) * t)\n return `rgb(${r},${g},${b})`\n }\n}\n\nComponent.memoize(Stocker.prototype, 'layout', false)\nComponent.memoize(Stocker.prototype, 'locationRule', false)\n"]}
1
+ {"version":3,"file":"stocker.js","sourceRoot":"","sources":["../src/stocker.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Stocker (AS/RS) Component\n *\n * Configurable automated storage/retrieval system:\n * - Independent L/R rack configuration (bays, levels, depth)\n * - Freely positioned In/Out ports\n * - Central aisle with crane (2-axis movement)\n */\n\nimport { Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\nimport { Stocker3d } from './stocker-3d.js'\n\n// ── Types ──\n\nexport interface RackConfig {\n bays: number\n levels: number\n depthCount: number\n}\n\nexport interface LocationRule {\n pattern: string // '{side}{bay}-{level}-{depth}'\n sideLabels: { L: string; R: string } // { L: 'A', R: 'B' }\n bayDir: 'ltr' | 'rtl' // 번호 방향\n levelDir: 'btt' | 'ttb' // 번호 방향 (bottom-to-top / top-to-bottom)\n bayStart: number // 시작 번호\n levelStart: number\n depthStart: number\n bayDigits: number // 자릿수 (0=패딩 없음)\n levelDigits: number\n depthDigits: number\n}\n\nexport interface CraneData {\n id?: string\n bay: number\n level: number\n side?: 'L' | 'R'\n status?: string // IDLE, MOVING, PICKING, PLACING\n carrier?: string\n}\n\nexport interface StockerCell {\n side: 'L' | 'R'\n bay: number\n level: number\n depth: number\n carrier?: string\n status?: string // FULL, EMPTY, RESERVED, ERROR, ...\n}\n\nexport interface StockerData {\n STATUS?: string\n // 단일 crane (하위 호환)\n CRANE_BAY?: number\n CRANE_LEVEL?: number\n CRANE_SIDE?: 'L' | 'R'\n CRANE_STATUS?: string\n CRANE_CARRIER?: string\n // 복수 crane\n CRANES?: string | CraneData[]\n CELLS?: string | StockerCell[]\n TOTAL_CAPACITY?: number\n CURRENT_COUNT?: number\n}\n\n// ── Layout ──\n\nexport type FrontSide = 'auto' | 'top' | 'bottom' | 'left' | 'right'\n\nexport interface RackLayout {\n x: number; y: number; w: number; h: number\n config: RackConfig\n}\n\nexport interface StockerLayout {\n width: number\n height: number\n left: number\n top: number\n vertical: boolean\n flipped: boolean\n along: number\n across: number\n leftRack: RackLayout | null\n rightRack: RackLayout | null\n aisle: { x: number; y: number; w: number; h: number }\n maxBays: number\n bayW: number\n}\n\nexport function computeLayout(state: any): StockerLayout {\n const { left = 0, top = 0, width = 200, height = 100, aisleRatio = 0.15 } = state\n const frontSide: FrontSide = state.frontSide || 'auto'\n\n let vertical: boolean\n let flipped: boolean\n\n switch (frontSide) {\n case 'left': vertical = false; flipped = false; break\n case 'right': vertical = false; flipped = true; break\n case 'top': vertical = true; flipped = false; break\n case 'bottom': vertical = true; flipped = true; break\n default: vertical = height > width; flipped = false; break\n }\n\n const along = vertical ? height : width\n const across = vertical ? width : height\n\n const lRack = parseRackConfig(state, 'l')\n const rRack = parseRackConfig(state, 'r')\n const hasLeft = lRack.bays > 0 && lRack.levels > 0\n const hasRight = rRack.bays > 0 && rRack.levels > 0\n const hasBoth = hasLeft && hasRight\n\n const maxBays = Math.max(lRack.bays || 0, rRack.bays || 0, 1)\n const bayW = along / maxBays\n\n const aisleSize = across * aisleRatio\n const rackAreaSize = across - aisleSize\n\n let leftLayout: RackLayout | null = null\n let rightLayout: RackLayout | null = null\n\n if (vertical) {\n if (hasBoth) {\n const rackW = rackAreaSize / 2\n leftLayout = { x: left, y: top, w: rackW, h: height, config: lRack }\n rightLayout = { x: left + rackW + aisleSize, y: top, w: rackW, h: height, config: rRack }\n } else if (hasLeft) {\n leftLayout = { x: left, y: top, w: rackAreaSize, h: height, config: lRack }\n } else if (hasRight) {\n rightLayout = { x: left + aisleSize, y: top, w: rackAreaSize, h: height, config: rRack }\n }\n const aisleX = leftLayout ? leftLayout.x + leftLayout.w : left\n const aisle = { x: aisleX, y: top, w: aisleSize, h: height }\n return { width, height, left, top, vertical, flipped, along, across, leftRack: leftLayout, rightRack: rightLayout, aisle, maxBays, bayW }\n } else {\n if (hasBoth) {\n const rackH = rackAreaSize / 2\n leftLayout = { x: left, y: top, w: width, h: rackH, config: lRack }\n rightLayout = { x: left, y: top + rackH + aisleSize, w: width, h: rackH, config: rRack }\n } else if (hasLeft) {\n leftLayout = { x: left, y: top, w: width, h: rackAreaSize, config: lRack }\n } else if (hasRight) {\n rightLayout = { x: left, y: top + aisleSize, w: width, h: rackAreaSize, config: rRack }\n }\n const aisleY = leftLayout ? leftLayout.y + leftLayout.h : top\n const aisle = { x: left, y: aisleY, w: width, h: aisleSize }\n return { width, height, left, top, vertical, flipped, along, across, leftRack: leftLayout, rightRack: rightLayout, aisle, maxBays, bayW }\n }\n}\n\nexport function parseRackConfig(state: any, prefix: 'l' | 'r'): RackConfig {\n return {\n bays: state[`${prefix}Bays`] ?? 10,\n levels: state[`${prefix}Levels`] ?? 5,\n depthCount: state[`${prefix}Depth`] ?? 1\n }\n}\n\n// ── Location ──\n\nexport const DEFAULT_LOCATION_RULE: LocationRule = {\n pattern: '{side}{bay}-{level}-{depth}',\n sideLabels: { L: 'L', R: 'R' },\n bayDir: 'ltr', levelDir: 'btt',\n bayStart: 1, levelStart: 1, depthStart: 1,\n bayDigits: 2, levelDigits: 2, depthDigits: 0\n}\n\nexport function parseLocationRule(state: any): LocationRule {\n const raw = state.locationRule\n if (!raw) return DEFAULT_LOCATION_RULE\n if (typeof raw === 'string') {\n try { return { ...DEFAULT_LOCATION_RULE, ...JSON.parse(raw) } } catch { return DEFAULT_LOCATION_RULE }\n }\n return { ...DEFAULT_LOCATION_RULE, ...raw }\n}\n\nfunction padNum(n: number, digits: number): string {\n if (digits <= 0) return String(n)\n return String(n).padStart(digits, '0')\n}\n\nexport function buildLocationId(\n rule: LocationRule, side: 'L' | 'R', bay: number, level: number, depth: number, rackConfig: RackConfig\n): string {\n const sideLabel = rule.sideLabels[side] || side\n const bayNum = rule.bayDir === 'rtl' ? rackConfig.bays - bay + rule.bayStart : bay - 1 + rule.bayStart\n const levelNum = rule.levelDir === 'ttb' ? rackConfig.levels - level + rule.levelStart : level - 1 + rule.levelStart\n const depthNum = depth - 1 + rule.depthStart\n return rule.pattern\n .replace(/{side}/gi, sideLabel)\n .replace(/{bay}/gi, padNum(bayNum, rule.bayDigits))\n .replace(/{level}/gi, padNum(levelNum, rule.levelDigits))\n .replace(/{depth}/gi, padNum(depthNum, rule.depthDigits))\n}\n\n// ── NATURE ──\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n { type: 'number', label: 'L-bays', name: 'lBays', property: { min: 0, max: 100, step: 1 } },\n { type: 'number', label: 'L-levels', name: 'lLevels', property: { min: 0, max: 20, step: 1 } },\n { type: 'number', label: 'L-depth', name: 'lDepth', property: { min: 1, max: 3, step: 1 } },\n { type: 'number', label: 'R-bays', name: 'rBays', property: { min: 0, max: 100, step: 1 } },\n { type: 'number', label: 'R-levels', name: 'rLevels', property: { min: 0, max: 20, step: 1 } },\n { type: 'number', label: 'R-depth', name: 'rDepth', property: { min: 1, max: 3, step: 1 } },\n { type: 'number', label: 'cranes', name: 'cranes', property: { min: 1, max: 4, step: 1 } },\n {\n type: 'select', label: 'front-side', name: 'frontSide',\n property: { options: [\n { display: 'Auto', value: 'auto' }, { display: 'Top', value: 'top' },\n { display: 'Bottom', value: 'bottom' }, { display: 'Left', value: 'left' },\n { display: 'Right', value: 'right' }\n ] }\n },\n { type: 'checkbox', label: 'hide-rack-frame', name: 'hideRackFrame' },\n { type: 'number', label: 'aisle-ratio', name: 'aisleRatio', property: { min: 0.05, max: 0.4, step: 0.01 } },\n { type: 'stocker-location', label: 'location-rule', name: 'locationRule' },\n { type: 'number', label: '3d-height', name: 'depth', property: { min: 1 } }\n ],\n help: 'scene/component/stocker'\n}\n\n// ── Colors ──\n\nconst COLORS = {\n rack: '#e0e0e0',\n rackStroke: '#999',\n aisle: '#d4d4c8',\n aisleRail: '#888',\n crane: '#ff6600',\n craneMast: '#cc5500',\n cellEmpty: '#f5f5f5',\n cellFull: '#4a9eff',\n cellReserved: '#ffcc00',\n cellError: '#e74c3c',\n}\n\n// ── Component ──\n\n@sceneComponent('stocker')\nexport class Stocker extends RectPath(Shape) {\n private _parsedCells: StockerCell[] = []\n private _parsedCranes: CraneData[] = []\n\n get nature() { return NATURE }\n\n\n buildRealObject(): RealObject | undefined {\n return new Stocker3d(this as any)\n }\n\n get layout(): StockerLayout {\n return computeLayout(this.state)\n }\n\n get locationRule(): LocationRule {\n return parseLocationRule(this.state)\n }\n\n get cells(): StockerCell[] {\n return this._parsedCells\n }\n\n get cranesData(): CraneData[] {\n return this._parsedCranes\n }\n\n getCellStatus(side: 'L' | 'R', bay: number, level: number, depth: number): string | undefined {\n return this._parsedCells.find(\n c => c.side === side && c.bay === bay && c.level === level && c.depth === depth\n )?.status\n }\n\n getLocationId(side: 'L' | 'R', bay: number, level: number, depth: number): string {\n const rackConfig = parseRackConfig(this.state, side === 'L' ? 'l' : 'r')\n return buildLocationId(this.locationRule, side, bay, level, depth, rackConfig)\n }\n\n // ── Data parsing ──\n\n onchangeData(_after: any, _before: any) {\n const data = (this.data || {}) as StockerData\n\n if (typeof data.CELLS === 'string') {\n try { this._parsedCells = JSON.parse(data.CELLS) } catch { this._parsedCells = [] }\n } else if (Array.isArray(data.CELLS)) {\n this._parsedCells = data.CELLS\n }\n\n if (data.CRANES) {\n if (typeof data.CRANES === 'string') {\n try {\n const parsed = JSON.parse(data.CRANES)\n this._parsedCranes = Array.isArray(parsed) ? parsed : []\n } catch { this._parsedCranes = [] }\n } else if (Array.isArray(data.CRANES)) {\n this._parsedCranes = data.CRANES\n }\n } else if (data.CRANE_BAY != null) {\n this._parsedCranes = [{\n id: 'CR1', bay: data.CRANE_BAY, level: data.CRANE_LEVEL ?? 1,\n side: data.CRANE_SIDE, status: data.CRANE_STATUS, carrier: data.CRANE_CARRIER\n }]\n }\n\n this.invalidate()\n }\n\n // ── 2D Rendering (top view) ──\n\n render(ctx: CanvasRenderingContext2D) {\n const { left = 0, top = 0, width = 200, height = 100 } = this.state\n const layout = this.layout\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n\n if (layout.leftRack) this._drawRack(ctx, layout.leftRack, 'L', layout)\n if (layout.rightRack) this._drawRack(ctx, layout.rightRack, 'R', layout)\n\n this._drawAisle(ctx, layout)\n this._drawCranes(ctx, layout)\n }\n\n private _visualBay(layout: StockerLayout, bay: number): number {\n return layout.flipped ? layout.maxBays - bay + 1 : bay\n }\n\n private _drawRack(ctx: CanvasRenderingContext2D, rack: RackLayout, side: 'L' | 'R', layout: StockerLayout) {\n const { bays, levels, depthCount } = rack.config\n const { vertical, bayW } = layout\n const depthCellSize = vertical ? rack.w / depthCount : rack.h / depthCount\n\n ctx.strokeStyle = COLORS.rackStroke\n ctx.lineWidth = 0.5\n\n for (let d = 0; d < depthCount; d++) {\n for (let b = 1; b <= bays; b++) {\n const vb = this._visualBay(layout, b)\n\n let cx: number, cy: number, cw: number, ch: number\n if (vertical) {\n cx = rack.x + d * depthCellSize\n cy = rack.y + (vb - 1) * bayW\n cw = depthCellSize\n ch = bayW\n } else {\n cx = rack.x + (vb - 1) * bayW\n cy = rack.y + d * depthCellSize\n cw = bayW\n ch = depthCellSize\n }\n\n let occupied = 0\n for (let l = 1; l <= levels; l++) {\n const s = this.getCellStatus(side, b, l, d + 1)\n if (s === 'FULL' || s === 'RESERVED') occupied++\n }\n\n const ratio = levels > 0 ? occupied / levels : 0\n ctx.fillStyle = ratio > 0\n ? this._blendColor(COLORS.cellEmpty, COLORS.cellFull, ratio)\n : COLORS.cellEmpty\n ctx.fillRect(cx, cy, cw, ch)\n ctx.strokeRect(cx, cy, cw, ch)\n }\n }\n }\n\n private _drawAisle(ctx: CanvasRenderingContext2D, layout: StockerLayout) {\n const { aisle, vertical } = layout\n\n ctx.fillStyle = COLORS.aisle\n ctx.fillRect(aisle.x, aisle.y, aisle.w, aisle.h)\n\n ctx.strokeStyle = COLORS.aisleRail\n ctx.lineWidth = 2\n ctx.beginPath()\n\n if (vertical) {\n const railX = aisle.x + aisle.w / 2\n ctx.moveTo(railX, aisle.y)\n ctx.lineTo(railX, aisle.y + aisle.h)\n } else {\n const railY = aisle.y + aisle.h / 2\n ctx.moveTo(aisle.x, railY)\n ctx.lineTo(aisle.x + aisle.w, railY)\n }\n ctx.stroke()\n }\n\n private _drawCranes(ctx: CanvasRenderingContext2D, layout: StockerLayout) {\n const { cranes: craneCount = 1 } = this.state\n const cranesData = this._parsedCranes\n const { aisle, maxBays, bayW, vertical } = layout\n\n const count = Math.max(cranesData.length, craneCount)\n const aisleShort = vertical ? aisle.w : aisle.h\n const craneSize = Math.min(bayW, aisleShort) * 0.6\n\n for (let i = 0; i < count; i++) {\n const cd = cranesData[i]\n const bay = cd?.bay ?? Math.round((i + 1) * maxBays / (count + 1))\n const vb = this._visualBay(layout, bay)\n\n let cx: number, cy: number\n if (vertical) {\n cx = aisle.x + aisle.w / 2\n cy = aisle.y + (vb - 0.5) * bayW\n } else {\n cx = aisle.x + (vb - 0.5) * bayW\n cy = aisle.y + aisle.h / 2\n }\n\n ctx.strokeStyle = COLORS.craneMast\n ctx.lineWidth = 2\n ctx.beginPath()\n if (vertical) {\n ctx.moveTo(aisle.x, cy)\n ctx.lineTo(aisle.x + aisle.w, cy)\n } else {\n ctx.moveTo(cx, aisle.y)\n ctx.lineTo(cx, aisle.y + aisle.h)\n }\n ctx.stroke()\n\n ctx.fillStyle = COLORS.crane\n ctx.fillRect(cx - craneSize / 2, cy - craneSize / 2, craneSize, craneSize)\n\n const label = cd?.id || `CR${i + 1}`\n ctx.fillStyle = '#fff'\n ctx.font = `${Math.max(craneSize * 0.4, 6)}px sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(label, cx, cy)\n }\n }\n\n private _blendColor(c1: string, c2: string, t: number): string {\n const parse = (c: string) => {\n const m = c.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)\n return m ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)] : [200, 200, 200]\n }\n const [r1, g1, b1] = parse(c1)\n const [r2, g2, b2] = parse(c2)\n const r = Math.round(r1 + (r2 - r1) * t)\n const g = Math.round(g1 + (g2 - g1) * t)\n const b = Math.round(b1 + (b2 - b1) * t)\n return `rgb(${r},${g},${b})`\n }\n}\n\nComponent.memoize(Stocker.prototype, 'layout', false)\nComponent.memoize(Stocker.prototype, 'locationRule', false)\n"]}
package/dist/tank.d.ts CHANGED
@@ -483,7 +483,6 @@ declare const MixedShape: (new (...args: any[]) => {
483
483
  set element(_v: HTMLElement | null): any;
484
484
  }) & typeof Shape;
485
485
  export declare class Tank extends MixedShape {
486
- is3dish(): boolean;
487
486
  buildRealObject(): RealObject | undefined;
488
487
  get nature(): ComponentNature;
489
488
  onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
package/dist/tank.js CHANGED
@@ -283,9 +283,6 @@ export class Tank3D extends RealObjectGroup {
283
283
  /* ── Component 클래스 ── */
284
284
  const MixedShape = ValueHolder(RectPath(Shape));
285
285
  let Tank = class Tank extends MixedShape {
286
- is3dish() {
287
- return true;
288
- }
289
286
  buildRealObject() {
290
287
  return new Tank3D(this);
291
288
  }
package/dist/tank.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tank.js","sourceRoot":"","sources":["../src/tank.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport {\n ComponentNature,\n RealObjectGroup,\n RealObject,\n RectPath,\n Shape,\n ValueHolder,\n sceneComponent\n} 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: 'value',\n name: 'value',\n property: 'value'\n },\n {\n type: 'color',\n label: 'liquid-color',\n name: 'liquidColor',\n property: 'liquidColor'\n }\n ],\n help: 'scene/component/tank'\n}\n\n/* ── 상수 ── */\nconst TANK_COLOR = '#aaaaaa'\nconst LIQUID_COLOR = '#4488ff'\nconst LIQUID_OPACITY = 0.8\n\n/* ── 게이지 ── */\nconst GAUGE_TEX_W = 64\nconst GAUGE_TEX_H = 256\nconst GAUGE_ARC = 0.22 // 라디안 (~13°) — 더 좁고 세련된 폭\nconst BEZEL_COLOR = '#2a2a2a'\n\n/* ── 2D 렌더 ── */\n\nfunction renderTank(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n value: number,\n liquidColor: string\n) {\n const capH = Math.min(w * 0.25, h * 0.15)\n const bodyY = y + capH\n const bodyH = h - capH\n\n // 외벽 — 본체 (불투명)\n ctx.fillStyle = TANK_COLOR\n ctx.fillRect(x, bodyY, w, bodyH)\n\n // 외벽 — 상단 둥근 캡\n ctx.beginPath()\n ctx.ellipse(x + w / 2, bodyY, w / 2, capH, 0, Math.PI, 0)\n ctx.fill()\n\n // 외벽 윤곽선\n ctx.strokeStyle = '#888888'\n ctx.lineWidth = 1.5\n ctx.beginPath()\n ctx.moveTo(x, bodyY)\n ctx.lineTo(x, bodyY + bodyH)\n ctx.lineTo(x + w, bodyY + bodyH)\n ctx.lineTo(x + w, bodyY)\n ctx.stroke()\n ctx.beginPath()\n ctx.ellipse(x + w / 2, bodyY, w / 2, capH, 0, Math.PI, 0)\n ctx.stroke()\n\n // ── 전면 게이지 ──\n const gw = Math.max(6, w * 0.15)\n const gPad = bodyH * 0.15\n const gx = x + (w - gw) / 2\n const gy = bodyY + gPad\n const gh = bodyH - gPad * 2\n const gr = gw / 2\n\n // 액체 채움\n const level = Math.max(0, Math.min(100, value)) / 100\n if (level > 0) {\n const fp = 2\n const fillH = (gh - fp * 2) * level\n const fillY = gy + gh - fp - fillH\n\n ctx.save()\n ctx.beginPath()\n ctx.roundRect(gx + fp, gy + fp, gw - fp * 2, gh - fp * 2, Math.max(0, gr - fp))\n ctx.clip()\n\n ctx.fillStyle = liquidColor || LIQUID_COLOR\n ctx.globalAlpha = LIQUID_OPACITY\n ctx.fillRect(gx + fp, fillY, gw - fp * 2, fillH)\n ctx.globalAlpha = 1\n ctx.restore()\n }\n\n // 눈금 (우측, 20% 단위)\n ctx.strokeStyle = 'rgba(255,255,255,0.45)'\n const tickTop = gy + 4\n const tickAreaH = gh - 8\n for (let pct = 20; pct <= 80; pct += 20) {\n const ty = tickTop + tickAreaH * (1 - pct / 100)\n const tw = pct === 50 ? gw * 0.35 : gw * 0.2\n ctx.lineWidth = pct === 50 ? 1 : 0.5\n ctx.beginPath()\n ctx.moveTo(gx + gw - tw - 1, ty)\n ctx.lineTo(gx + gw - 1, ty)\n ctx.stroke()\n }\n\n // 게이지 테두리 (라운드)\n ctx.strokeStyle = 'rgba(255,255,255,0.2)'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.stroke()\n\n // 수치 (게이지 중앙)\n const pctText = `${Math.round(value)}%`\n const fontSize = Math.max(7, Math.round(gw * 0.55))\n ctx.font = `bold ${fontSize}px sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.shadowColor = 'rgba(0,0,0,0.7)'\n ctx.shadowBlur = 2\n ctx.fillStyle = '#ffffff'\n ctx.fillText(pctText, gx + gw / 2, gy + gh / 2)\n ctx.shadowColor = 'transparent'\n ctx.shadowBlur = 0\n\n // bounds path 등록\n ctx.beginPath()\n ctx.rect(x, y, w, h)\n}\n\n/* ── 3D 렌더 ── */\n\nexport class Tank3D extends RealObjectGroup {\n private _gaugeCanvas!: HTMLCanvasElement\n private _gaugeCtx!: CanvasRenderingContext2D\n private _gaugeTexture!: THREE.CanvasTexture\n private _gaugeMesh!: THREE.Mesh\n\n // build 시 저장\n private _bodyRadius = 0\n private _bodyDepth = 0\n private _domeH = 0\n\n build() {\n super.build()\n\n const { width, height } = this.component.bounds\n const { depth } = this.component.state\n const d = depth || Math.max(width, height) * 2\n\n const radius = Math.min(width, height) / 2\n const domeH = radius * 0.5\n const bodyH = d - domeH\n\n this._bodyRadius = radius\n this._bodyDepth = bodyH\n this._domeH = domeH\n\n const gaugeH = bodyH * 0.55\n\n // ── 솔리드 탱크 본체 ──\n const tankMat = new THREE.MeshStandardMaterial({\n color: TANK_COLOR,\n roughness: 0.35,\n metalness: 0.5\n })\n\n // 원기둥 (닫힌 양 끝)\n const wallGeo = new THREE.CylinderGeometry(radius, radius, bodyH, 32)\n const wallMesh = new THREE.Mesh(wallGeo, tankMat)\n wallMesh.position.y = bodyH / 2\n wallMesh.castShadow = true\n this.object3d.add(wallMesh)\n\n // 상단 반구 돔\n const domeGeo = new THREE.SphereGeometry(radius, 32, 16, 0, Math.PI * 2, 0, Math.PI / 2)\n const domeMesh = new THREE.Mesh(domeGeo, tankMat)\n domeMesh.position.y = bodyH\n domeMesh.castShadow = true\n this.object3d.add(domeMesh)\n\n // ── 게이지 (곡면, 단일 메시 — 캔버스로 전부 그림) ──\n this._gaugeCanvas = document.createElement('canvas')\n this._gaugeCanvas.width = GAUGE_TEX_W\n this._gaugeCanvas.height = GAUGE_TEX_H\n this._gaugeCtx = this._gaugeCanvas.getContext('2d')!\n\n this._gaugeTexture = new THREE.CanvasTexture(this._gaugeCanvas)\n this._gaugeTexture.minFilter = THREE.LinearFilter\n\n const gaugeR = radius * 1.04\n const gaugeGeo = new THREE.CylinderGeometry(\n gaugeR, gaugeR, gaugeH, 24, 1, true,\n -GAUGE_ARC / 2, GAUGE_ARC\n )\n const gaugeMat = new THREE.MeshBasicMaterial({\n map: this._gaugeTexture,\n transparent: true,\n alphaTest: 0.05\n })\n this._gaugeMesh = new THREE.Mesh(gaugeGeo, gaugeMat)\n this._gaugeMesh.position.y = bodyH / 2\n this.object3d.add(this._gaugeMesh)\n\n // 게이지 그리기\n this._drawGauge()\n\n // 수직 중앙 정렬\n const totalH = bodyH + domeH\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n\n private _drawGauge() {\n const ctx = this._gaugeCtx\n const w = GAUGE_TEX_W\n const h = GAUGE_TEX_H\n const comp = this.component as unknown as Tank\n const value = Math.max(0, Math.min(100, comp.value ?? 0))\n const level = value / 100\n const liquidColor = comp.getState('liquidColor') || LIQUID_COLOR\n\n // 레이아웃 — 캡슐 형태 유리 영역만\n const gx = 6\n const gy = 10\n const gw = w - gx * 2\n const gh = h - gy * 2\n const gr = gw / 2 // 캡슐 라운드\n\n ctx.clearRect(0, 0, w, h)\n\n // ── 빈 영역 (어두운 배경) ──\n ctx.fillStyle = 'rgba(15, 20, 25, 0.8)'\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.fill()\n\n // ── 액체 채움 ──\n if (level > 0) {\n const fillH = Math.round(gh * level)\n const fillY = gy + gh - fillH\n\n ctx.save()\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.clip()\n\n ctx.fillStyle = liquidColor\n ctx.globalAlpha = LIQUID_OPACITY\n ctx.fillRect(gx, fillY, gw, fillH)\n\n // 수면 하이라이트\n ctx.globalAlpha = 0.3\n const surfGrad = ctx.createLinearGradient(0, fillY, 0, fillY + 4)\n surfGrad.addColorStop(0, '#ffffff')\n surfGrad.addColorStop(1, 'transparent')\n ctx.fillStyle = surfGrad\n ctx.fillRect(gx, fillY, gw, 4)\n\n ctx.globalAlpha = 1\n ctx.restore()\n }\n\n // ── 눈금 (우측, 20% 단위) ──\n ctx.strokeStyle = 'rgba(255,255,255,0.4)'\n for (let pct = 20; pct <= 80; pct += 20) {\n const ty = gy + gh * (1 - pct / 100)\n const tw = pct === 50 ? gw * 0.35 : gw * 0.22\n ctx.lineWidth = pct === 50 ? 1.5 : 1\n ctx.beginPath()\n ctx.moveTo(gx + gw - tw, ty)\n ctx.lineTo(gx + gw, ty)\n ctx.stroke()\n }\n\n // ── 유리 반사 (좌측 하이라이트) ──\n ctx.save()\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.clip()\n const hlGrad = ctx.createLinearGradient(gx, 0, gx + gw, 0)\n hlGrad.addColorStop(0, 'rgba(255,255,255,0.12)')\n hlGrad.addColorStop(0.3, 'rgba(255,255,255,0.03)')\n hlGrad.addColorStop(1, 'rgba(255,255,255,0)')\n ctx.fillStyle = hlGrad\n ctx.fillRect(gx, gy, gw, gh)\n ctx.restore()\n\n // ── 유리 테두리 ──\n ctx.strokeStyle = 'rgba(255,255,255,0.15)'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.stroke()\n\n // ── 수치 (게이지 중앙) ──\n ctx.fillStyle = '#ffffff'\n ctx.font = 'bold 14px sans-serif'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.shadowColor = 'rgba(0,0,0,0.7)'\n ctx.shadowBlur = 3\n ctx.fillText(`${Math.round(value)}%`, w / 2, gy + gh / 2)\n ctx.shadowColor = 'transparent'\n ctx.shadowBlur = 0\n\n this._gaugeTexture.needsUpdate = true\n }\n\n updateFillLevel() {\n this._drawGauge()\n }\n\n update() {\n super.update()\n this.updateFillLevel()\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 || 'liquidColor' in after) {\n this.updateFillLevel()\n }\n }\n}\n\n/* ── Component 클래스 ── */\n\nconst MixedShape = ValueHolder(RectPath(Shape))\n\n@sceneComponent('tank')\nexport class Tank extends MixedShape {\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Tank3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n super.onchange(after, before)\n\n if ('value' in after || 'liquidColor' in after) {\n this.invalidate()\n }\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n renderTank(ctx, left, top, width, height, this.value, this.getState('liquidColor') || LIQUID_COLOR)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n\n}\n"]}
1
+ {"version":3,"file":"tank.js","sourceRoot":"","sources":["../src/tank.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport {\n ComponentNature,\n RealObjectGroup,\n RealObject,\n RectPath,\n Shape,\n ValueHolder,\n sceneComponent\n} 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: 'value',\n name: 'value',\n property: 'value'\n },\n {\n type: 'color',\n label: 'liquid-color',\n name: 'liquidColor',\n property: 'liquidColor'\n }\n ],\n help: 'scene/component/tank'\n}\n\n/* ── 상수 ── */\nconst TANK_COLOR = '#aaaaaa'\nconst LIQUID_COLOR = '#4488ff'\nconst LIQUID_OPACITY = 0.8\n\n/* ── 게이지 ── */\nconst GAUGE_TEX_W = 64\nconst GAUGE_TEX_H = 256\nconst GAUGE_ARC = 0.22 // 라디안 (~13°) — 더 좁고 세련된 폭\nconst BEZEL_COLOR = '#2a2a2a'\n\n/* ── 2D 렌더 ── */\n\nfunction renderTank(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n value: number,\n liquidColor: string\n) {\n const capH = Math.min(w * 0.25, h * 0.15)\n const bodyY = y + capH\n const bodyH = h - capH\n\n // 외벽 — 본체 (불투명)\n ctx.fillStyle = TANK_COLOR\n ctx.fillRect(x, bodyY, w, bodyH)\n\n // 외벽 — 상단 둥근 캡\n ctx.beginPath()\n ctx.ellipse(x + w / 2, bodyY, w / 2, capH, 0, Math.PI, 0)\n ctx.fill()\n\n // 외벽 윤곽선\n ctx.strokeStyle = '#888888'\n ctx.lineWidth = 1.5\n ctx.beginPath()\n ctx.moveTo(x, bodyY)\n ctx.lineTo(x, bodyY + bodyH)\n ctx.lineTo(x + w, bodyY + bodyH)\n ctx.lineTo(x + w, bodyY)\n ctx.stroke()\n ctx.beginPath()\n ctx.ellipse(x + w / 2, bodyY, w / 2, capH, 0, Math.PI, 0)\n ctx.stroke()\n\n // ── 전면 게이지 ──\n const gw = Math.max(6, w * 0.15)\n const gPad = bodyH * 0.15\n const gx = x + (w - gw) / 2\n const gy = bodyY + gPad\n const gh = bodyH - gPad * 2\n const gr = gw / 2\n\n // 액체 채움\n const level = Math.max(0, Math.min(100, value)) / 100\n if (level > 0) {\n const fp = 2\n const fillH = (gh - fp * 2) * level\n const fillY = gy + gh - fp - fillH\n\n ctx.save()\n ctx.beginPath()\n ctx.roundRect(gx + fp, gy + fp, gw - fp * 2, gh - fp * 2, Math.max(0, gr - fp))\n ctx.clip()\n\n ctx.fillStyle = liquidColor || LIQUID_COLOR\n ctx.globalAlpha = LIQUID_OPACITY\n ctx.fillRect(gx + fp, fillY, gw - fp * 2, fillH)\n ctx.globalAlpha = 1\n ctx.restore()\n }\n\n // 눈금 (우측, 20% 단위)\n ctx.strokeStyle = 'rgba(255,255,255,0.45)'\n const tickTop = gy + 4\n const tickAreaH = gh - 8\n for (let pct = 20; pct <= 80; pct += 20) {\n const ty = tickTop + tickAreaH * (1 - pct / 100)\n const tw = pct === 50 ? gw * 0.35 : gw * 0.2\n ctx.lineWidth = pct === 50 ? 1 : 0.5\n ctx.beginPath()\n ctx.moveTo(gx + gw - tw - 1, ty)\n ctx.lineTo(gx + gw - 1, ty)\n ctx.stroke()\n }\n\n // 게이지 테두리 (라운드)\n ctx.strokeStyle = 'rgba(255,255,255,0.2)'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.stroke()\n\n // 수치 (게이지 중앙)\n const pctText = `${Math.round(value)}%`\n const fontSize = Math.max(7, Math.round(gw * 0.55))\n ctx.font = `bold ${fontSize}px sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.shadowColor = 'rgba(0,0,0,0.7)'\n ctx.shadowBlur = 2\n ctx.fillStyle = '#ffffff'\n ctx.fillText(pctText, gx + gw / 2, gy + gh / 2)\n ctx.shadowColor = 'transparent'\n ctx.shadowBlur = 0\n\n // bounds path 등록\n ctx.beginPath()\n ctx.rect(x, y, w, h)\n}\n\n/* ── 3D 렌더 ── */\n\nexport class Tank3D extends RealObjectGroup {\n private _gaugeCanvas!: HTMLCanvasElement\n private _gaugeCtx!: CanvasRenderingContext2D\n private _gaugeTexture!: THREE.CanvasTexture\n private _gaugeMesh!: THREE.Mesh\n\n // build 시 저장\n private _bodyRadius = 0\n private _bodyDepth = 0\n private _domeH = 0\n\n build() {\n super.build()\n\n const { width, height } = this.component.bounds\n const { depth } = this.component.state\n const d = depth || Math.max(width, height) * 2\n\n const radius = Math.min(width, height) / 2\n const domeH = radius * 0.5\n const bodyH = d - domeH\n\n this._bodyRadius = radius\n this._bodyDepth = bodyH\n this._domeH = domeH\n\n const gaugeH = bodyH * 0.55\n\n // ── 솔리드 탱크 본체 ──\n const tankMat = new THREE.MeshStandardMaterial({\n color: TANK_COLOR,\n roughness: 0.35,\n metalness: 0.5\n })\n\n // 원기둥 (닫힌 양 끝)\n const wallGeo = new THREE.CylinderGeometry(radius, radius, bodyH, 32)\n const wallMesh = new THREE.Mesh(wallGeo, tankMat)\n wallMesh.position.y = bodyH / 2\n wallMesh.castShadow = true\n this.object3d.add(wallMesh)\n\n // 상단 반구 돔\n const domeGeo = new THREE.SphereGeometry(radius, 32, 16, 0, Math.PI * 2, 0, Math.PI / 2)\n const domeMesh = new THREE.Mesh(domeGeo, tankMat)\n domeMesh.position.y = bodyH\n domeMesh.castShadow = true\n this.object3d.add(domeMesh)\n\n // ── 게이지 (곡면, 단일 메시 — 캔버스로 전부 그림) ──\n this._gaugeCanvas = document.createElement('canvas')\n this._gaugeCanvas.width = GAUGE_TEX_W\n this._gaugeCanvas.height = GAUGE_TEX_H\n this._gaugeCtx = this._gaugeCanvas.getContext('2d')!\n\n this._gaugeTexture = new THREE.CanvasTexture(this._gaugeCanvas)\n this._gaugeTexture.minFilter = THREE.LinearFilter\n\n const gaugeR = radius * 1.04\n const gaugeGeo = new THREE.CylinderGeometry(\n gaugeR, gaugeR, gaugeH, 24, 1, true,\n -GAUGE_ARC / 2, GAUGE_ARC\n )\n const gaugeMat = new THREE.MeshBasicMaterial({\n map: this._gaugeTexture,\n transparent: true,\n alphaTest: 0.05\n })\n this._gaugeMesh = new THREE.Mesh(gaugeGeo, gaugeMat)\n this._gaugeMesh.position.y = bodyH / 2\n this.object3d.add(this._gaugeMesh)\n\n // 게이지 그리기\n this._drawGauge()\n\n // 수직 중앙 정렬\n const totalH = bodyH + domeH\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n\n private _drawGauge() {\n const ctx = this._gaugeCtx\n const w = GAUGE_TEX_W\n const h = GAUGE_TEX_H\n const comp = this.component as unknown as Tank\n const value = Math.max(0, Math.min(100, comp.value ?? 0))\n const level = value / 100\n const liquidColor = comp.getState('liquidColor') || LIQUID_COLOR\n\n // 레이아웃 — 캡슐 형태 유리 영역만\n const gx = 6\n const gy = 10\n const gw = w - gx * 2\n const gh = h - gy * 2\n const gr = gw / 2 // 캡슐 라운드\n\n ctx.clearRect(0, 0, w, h)\n\n // ── 빈 영역 (어두운 배경) ──\n ctx.fillStyle = 'rgba(15, 20, 25, 0.8)'\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.fill()\n\n // ── 액체 채움 ──\n if (level > 0) {\n const fillH = Math.round(gh * level)\n const fillY = gy + gh - fillH\n\n ctx.save()\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.clip()\n\n ctx.fillStyle = liquidColor\n ctx.globalAlpha = LIQUID_OPACITY\n ctx.fillRect(gx, fillY, gw, fillH)\n\n // 수면 하이라이트\n ctx.globalAlpha = 0.3\n const surfGrad = ctx.createLinearGradient(0, fillY, 0, fillY + 4)\n surfGrad.addColorStop(0, '#ffffff')\n surfGrad.addColorStop(1, 'transparent')\n ctx.fillStyle = surfGrad\n ctx.fillRect(gx, fillY, gw, 4)\n\n ctx.globalAlpha = 1\n ctx.restore()\n }\n\n // ── 눈금 (우측, 20% 단위) ──\n ctx.strokeStyle = 'rgba(255,255,255,0.4)'\n for (let pct = 20; pct <= 80; pct += 20) {\n const ty = gy + gh * (1 - pct / 100)\n const tw = pct === 50 ? gw * 0.35 : gw * 0.22\n ctx.lineWidth = pct === 50 ? 1.5 : 1\n ctx.beginPath()\n ctx.moveTo(gx + gw - tw, ty)\n ctx.lineTo(gx + gw, ty)\n ctx.stroke()\n }\n\n // ── 유리 반사 (좌측 하이라이트) ──\n ctx.save()\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.clip()\n const hlGrad = ctx.createLinearGradient(gx, 0, gx + gw, 0)\n hlGrad.addColorStop(0, 'rgba(255,255,255,0.12)')\n hlGrad.addColorStop(0.3, 'rgba(255,255,255,0.03)')\n hlGrad.addColorStop(1, 'rgba(255,255,255,0)')\n ctx.fillStyle = hlGrad\n ctx.fillRect(gx, gy, gw, gh)\n ctx.restore()\n\n // ── 유리 테두리 ──\n ctx.strokeStyle = 'rgba(255,255,255,0.15)'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.roundRect(gx, gy, gw, gh, gr)\n ctx.stroke()\n\n // ── 수치 (게이지 중앙) ──\n ctx.fillStyle = '#ffffff'\n ctx.font = 'bold 14px sans-serif'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.shadowColor = 'rgba(0,0,0,0.7)'\n ctx.shadowBlur = 3\n ctx.fillText(`${Math.round(value)}%`, w / 2, gy + gh / 2)\n ctx.shadowColor = 'transparent'\n ctx.shadowBlur = 0\n\n this._gaugeTexture.needsUpdate = true\n }\n\n updateFillLevel() {\n this._drawGauge()\n }\n\n update() {\n super.update()\n this.updateFillLevel()\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 || 'liquidColor' in after) {\n this.updateFillLevel()\n }\n }\n}\n\n/* ── Component 클래스 ── */\n\nconst MixedShape = ValueHolder(RectPath(Shape))\n\n@sceneComponent('tank')\nexport class Tank extends MixedShape {\n buildRealObject(): RealObject | undefined {\n return new Tank3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n super.onchange(after, before)\n\n if ('value' in after || 'liquidColor' in after) {\n this.invalidate()\n }\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n renderTank(ctx, left, top, width, height, this.value, this.getState('liquidColor') || LIQUID_COLOR)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n\n}\n"]}
@@ -0,0 +1,18 @@
1
+ declare const _default: {
2
+ type: string;
3
+ description: string;
4
+ group: string;
5
+ icon: string;
6
+ model: {
7
+ type: string;
8
+ left: number;
9
+ top: number;
10
+ width: number;
11
+ height: number;
12
+ depth: number;
13
+ fillStyle: string;
14
+ strokeStyle: string;
15
+ alpha: number;
16
+ };
17
+ };
18
+ export default _default;
@@ -0,0 +1,19 @@
1
+ const icon = new URL('../../icons/wall.png', import.meta.url).href;
2
+ export default {
3
+ type: 'floor-plate',
4
+ description: 'floor plate for multi-story layout',
5
+ group: '3D' /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|IoT|3D|warehouse|form|etc */,
6
+ icon,
7
+ model: {
8
+ type: 'floor-plate',
9
+ left: 100,
10
+ top: 100,
11
+ width: 500,
12
+ height: 500,
13
+ depth: 2,
14
+ fillStyle: '#e8e8e8',
15
+ strokeStyle: '#999999',
16
+ alpha: 0.7
17
+ }
18
+ };
19
+ //# sourceMappingURL=floor-plate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floor-plate.js","sourceRoot":"","sources":["../../src/templates/floor-plate.ts"],"names":[],"mappings":"AAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAElE,eAAe;IACb,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,oCAAoC;IACjD,KAAK,EAAE,IAAI,CAAC,gGAAgG;IAC5G,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,GAAG;QACT,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,SAAS;QACpB,WAAW,EAAE,SAAS;QACtB,KAAK,EAAE,GAAG;KACX;CACF,CAAA","sourcesContent":["const icon = new URL('../../icons/wall.png', import.meta.url).href\n\nexport default {\n type: 'floor-plate',\n description: 'floor plate for multi-story layout',\n group: '3D' /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|IoT|3D|warehouse|form|etc */,\n icon,\n model: {\n type: 'floor-plate',\n left: 100,\n top: 100,\n width: 500,\n height: 500,\n depth: 2,\n fillStyle: '#e8e8e8',\n strokeStyle: '#999999',\n alpha: 0.7\n }\n}\n"]}
@@ -7,6 +7,7 @@ import sphere from './sphere.js';
7
7
  import banner from './banner.js';
8
8
  import sprite from './sprite.js';
9
9
  import wall from './wall.js';
10
+ import floorPlate from './floor-plate.js';
10
11
  import desk from './desk.js';
11
12
  import camera from './camera.js';
12
13
  import light from './light.js';
@@ -31,6 +32,7 @@ export default [
31
32
  sprite,
32
33
  banner,
33
34
  wall,
35
+ floorPlate,
34
36
  desk,
35
37
  GLTFObject,
36
38
  signalTower,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,mBAAmB,CAAA;AAC9C,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,QAAQ,MAAM,eAAe,CAAA;AACpC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AACzC,OAAO,WAAW,MAAM,mBAAmB,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,WAAW,MAAM,mBAAmB,CAAA;AAE3C,eAAe;IACb,cAAc;IACd,UAAU;IACV,QAAQ;IACR,SAAS;IACT,MAAM;IACN,KAAK;IACL,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,UAAU;IACV,WAAW;IACX,IAAI;IACJ,OAAO;IACP,OAAO;IACP,OAAO;IACP,WAAW;CACZ,CAAA","sourcesContent":["import threeContainer from './3d-container.js'\nimport visualizer from './visualizer.js'\nimport rackTable from './rack-table.js'\nimport cube from './cube.js'\nimport cylinder from './cylinder.js'\nimport sphere from './sphere.js'\nimport banner from './banner.js'\nimport sprite from './sprite.js'\nimport wall from './wall.js'\nimport desk from './desk.js'\nimport camera from './camera.js'\nimport light from './light.js'\nimport GLTFObject from './gltf-object.js'\nimport signalTower from './signal-tower.js'\nimport tank from './tank.js'\nimport vehicle from './vehicle.js'\nimport carrier from './carrier.js'\nimport stockHub from './stock-hub.js'\nimport stocker from './stocker.js'\nimport stockerPort from './stocker-port.js'\n\nexport default [\n threeContainer,\n visualizer,\n stockHub,\n rackTable,\n camera,\n light,\n cube,\n cylinder,\n sphere,\n sprite,\n banner,\n wall,\n desk,\n GLTFObject,\n signalTower,\n tank,\n vehicle,\n carrier,\n stocker,\n stockerPort\n]\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,mBAAmB,CAAA;AAC9C,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,QAAQ,MAAM,eAAe,CAAA;AACpC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AACzC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AACzC,OAAO,WAAW,MAAM,mBAAmB,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,WAAW,MAAM,mBAAmB,CAAA;AAE3C,eAAe;IACb,cAAc;IACd,UAAU;IACV,QAAQ;IACR,SAAS;IACT,MAAM;IACN,KAAK;IACL,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,UAAU;IACV,IAAI;IACJ,UAAU;IACV,WAAW;IACX,IAAI;IACJ,OAAO;IACP,OAAO;IACP,OAAO;IACP,WAAW;CACZ,CAAA","sourcesContent":["import threeContainer from './3d-container.js'\nimport visualizer from './visualizer.js'\nimport rackTable from './rack-table.js'\nimport cube from './cube.js'\nimport cylinder from './cylinder.js'\nimport sphere from './sphere.js'\nimport banner from './banner.js'\nimport sprite from './sprite.js'\nimport wall from './wall.js'\nimport floorPlate from './floor-plate.js'\nimport desk from './desk.js'\nimport camera from './camera.js'\nimport light from './light.js'\nimport GLTFObject from './gltf-object.js'\nimport signalTower from './signal-tower.js'\nimport tank from './tank.js'\nimport vehicle from './vehicle.js'\nimport carrier from './carrier.js'\nimport stockHub from './stock-hub.js'\nimport stocker from './stocker.js'\nimport stockerPort from './stocker-port.js'\n\nexport default [\n threeContainer,\n visualizer,\n stockHub,\n rackTable,\n camera,\n light,\n cube,\n cylinder,\n sphere,\n sprite,\n banner,\n wall,\n floorPlate,\n desk,\n GLTFObject,\n signalTower,\n tank,\n vehicle,\n carrier,\n stocker,\n stockerPort\n]\n"]}
package/dist/vehicle.d.ts CHANGED
@@ -240,7 +240,6 @@ declare const Vehicle_base: (new (...args: any[]) => {
240
240
  set element(_v: HTMLElement | null): any;
241
241
  }) & typeof Shape;
242
242
  export declare class Vehicle extends Vehicle_base {
243
- is3dish(): boolean;
244
243
  buildRealObject(): RealObject | undefined;
245
244
  get nature(): ComponentNature;
246
245
  render(ctx: CanvasRenderingContext2D): void;
package/dist/vehicle.js CHANGED
@@ -108,9 +108,6 @@ function renderVehicle(ctx, x, y, w, h, fillStyle, platformColor) {
108
108
  ctx.fill();
109
109
  }
110
110
  let Vehicle = class Vehicle extends RectPath(Shape) {
111
- is3dish() {
112
- return true;
113
- }
114
111
  buildRealObject() {
115
112
  return new Vehicle3D(this);
116
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vehicle.js","sourceRoot":"","sources":["../src/vehicle.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { ComponentNature, RectPath, Shape, sceneComponent, RealObject } from '@hatiolab/things-scene'\nimport * as THREE from 'three'\nimport { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'color',\n label: 'platform-color',\n name: 'platformColor',\n property: 'platformColor'\n }\n ],\n help: 'scene/component/vehicle'\n}\n\nconst DEFAULT_PLATFORM_COLOR = '#333333'\nconst DEFAULT_BODY_COLOR = '#f0f0f0'\nconst BUMPER_COLOR = '#222222'\n\nexport class Vehicle3D extends RealObject {\n build() {\n super.build()\n\n var { width, height, depth, fillStyle, platformColor } = this.component.state\n\n var w = width\n var h = height\n var d = depth || 50\n\n // 비율: 하단 범퍼 10%, 본체 58%, 간격 4%, 플랫폼 28%\n var bumperH = d * 0.10\n var bodyH = d * 0.58\n var gapH = d * 0.04\n var platH = d * 0.28\n var totalH = bumperH + bodyH + gapH + platH\n\n var cornerR = Math.min(w, h, bodyH) * 0.12\n\n // ── 하단 범퍼 밴드 (본체보다 약간 넓게 돌출) ──\n var bumperPad = Math.min(w, h) * 0.03\n var bumperCornerR = Math.min(w + bumperPad * 2, h + bumperPad * 2, bumperH) * 0.2\n var bumperGeo = new RoundedBoxGeometry(w + bumperPad * 2, bumperH, h + bumperPad * 2, 4, bumperCornerR)\n var bumperMat = new THREE.MeshStandardMaterial({\n color: BUMPER_COLOR,\n roughness: 0.8,\n metalness: 0.1\n })\n var bumper = new THREE.Mesh(bumperGeo, bumperMat)\n bumper.position.y = bumperH / 2\n bumper.castShadow = true\n this.object3d.add(bumper)\n\n // ── 본체 (둥근 모서리, 밝은색) ──\n var bodyGeo = new RoundedBoxGeometry(w, bodyH, h, 4, cornerR)\n var bodyMat = new THREE.MeshStandardMaterial({\n color: fillStyle || DEFAULT_BODY_COLOR,\n roughness: 0.3,\n metalness: 0.05\n })\n var body = new THREE.Mesh(bodyGeo, bodyMat)\n body.position.y = bumperH + bodyH / 2\n body.castShadow = true\n this.object3d.add(body)\n\n // ── 상단 플랫폼 (본체보다 약간 안쪽, 어두운색) ──\n var platInset = Math.min(w, h) * 0.04\n var platCornerR = Math.min(w - platInset * 2, h - platInset * 2, platH) * 0.15\n var platGeo = new RoundedBoxGeometry(w - platInset * 2, platH, h - platInset * 2, 4, platCornerR)\n var platMat = new THREE.MeshStandardMaterial({\n color: platformColor || DEFAULT_PLATFORM_COLOR,\n roughness: 0.5,\n metalness: 0.15\n })\n var plat = new THREE.Mesh(platGeo, platMat)\n plat.position.y = bumperH + bodyH + gapH + platH / 2\n plat.castShadow = true\n this.object3d.add(plat)\n\n // 수직 중앙 정렬\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n}\n\n/* ── 2D 렌더 ── */\n\nfunction renderVehicle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n fillStyle: string,\n platformColor: string\n) {\n var r = Math.min(w, h) * 0.1\n var bumperH = Math.max(3, h * 0.10)\n var platH = Math.max(4, h * 0.25)\n var platInset = Math.min(w, h) * 0.04\n\n // 하단 범퍼 밴드 (본체보다 약간 넓게)\n var bumperPad = Math.min(w, h) * 0.02\n ctx.fillStyle = BUMPER_COLOR\n ctx.beginPath()\n ctx.roundRect(x - bumperPad, y + h - bumperH, w + bumperPad * 2, bumperH, [0, 0, r, r])\n ctx.fill()\n\n // 본체 (둥근 사각형)\n ctx.fillStyle = fillStyle || DEFAULT_BODY_COLOR\n ctx.beginPath()\n ctx.roundRect(x, y + platH + 2, w, h - platH - bumperH - 2, r * 0.5)\n ctx.fill()\n\n ctx.strokeStyle = '#dddddd'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.roundRect(x, y + platH + 2, w, h - platH - bumperH - 2, r * 0.5)\n ctx.stroke()\n\n // 상단 플랫폼 (약간 안쪽)\n ctx.fillStyle = platformColor || DEFAULT_PLATFORM_COLOR\n ctx.beginPath()\n ctx.roundRect(x + platInset, y, w - platInset * 2, platH, [r, r, 0, 0])\n ctx.fill()\n}\n\n@sceneComponent('vehicle')\nexport class Vehicle extends RectPath(Shape) {\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Vehicle3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n var fillStyle = this.getState('fillStyle')\n var platformColor = this.getState('platformColor')\n\n renderVehicle(ctx, left, top, width, height, fillStyle, platformColor)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n}\n"]}
1
+ {"version":3,"file":"vehicle.js","sourceRoot":"","sources":["../src/vehicle.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { ComponentNature, RectPath, Shape, sceneComponent, RealObject } from '@hatiolab/things-scene'\nimport * as THREE from 'three'\nimport { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'color',\n label: 'platform-color',\n name: 'platformColor',\n property: 'platformColor'\n }\n ],\n help: 'scene/component/vehicle'\n}\n\nconst DEFAULT_PLATFORM_COLOR = '#333333'\nconst DEFAULT_BODY_COLOR = '#f0f0f0'\nconst BUMPER_COLOR = '#222222'\n\nexport class Vehicle3D extends RealObject {\n build() {\n super.build()\n\n var { width, height, depth, fillStyle, platformColor } = this.component.state\n\n var w = width\n var h = height\n var d = depth || 50\n\n // 비율: 하단 범퍼 10%, 본체 58%, 간격 4%, 플랫폼 28%\n var bumperH = d * 0.10\n var bodyH = d * 0.58\n var gapH = d * 0.04\n var platH = d * 0.28\n var totalH = bumperH + bodyH + gapH + platH\n\n var cornerR = Math.min(w, h, bodyH) * 0.12\n\n // ── 하단 범퍼 밴드 (본체보다 약간 넓게 돌출) ──\n var bumperPad = Math.min(w, h) * 0.03\n var bumperCornerR = Math.min(w + bumperPad * 2, h + bumperPad * 2, bumperH) * 0.2\n var bumperGeo = new RoundedBoxGeometry(w + bumperPad * 2, bumperH, h + bumperPad * 2, 4, bumperCornerR)\n var bumperMat = new THREE.MeshStandardMaterial({\n color: BUMPER_COLOR,\n roughness: 0.8,\n metalness: 0.1\n })\n var bumper = new THREE.Mesh(bumperGeo, bumperMat)\n bumper.position.y = bumperH / 2\n bumper.castShadow = true\n this.object3d.add(bumper)\n\n // ── 본체 (둥근 모서리, 밝은색) ──\n var bodyGeo = new RoundedBoxGeometry(w, bodyH, h, 4, cornerR)\n var bodyMat = new THREE.MeshStandardMaterial({\n color: fillStyle || DEFAULT_BODY_COLOR,\n roughness: 0.3,\n metalness: 0.05\n })\n var body = new THREE.Mesh(bodyGeo, bodyMat)\n body.position.y = bumperH + bodyH / 2\n body.castShadow = true\n this.object3d.add(body)\n\n // ── 상단 플랫폼 (본체보다 약간 안쪽, 어두운색) ──\n var platInset = Math.min(w, h) * 0.04\n var platCornerR = Math.min(w - platInset * 2, h - platInset * 2, platH) * 0.15\n var platGeo = new RoundedBoxGeometry(w - platInset * 2, platH, h - platInset * 2, 4, platCornerR)\n var platMat = new THREE.MeshStandardMaterial({\n color: platformColor || DEFAULT_PLATFORM_COLOR,\n roughness: 0.5,\n metalness: 0.15\n })\n var plat = new THREE.Mesh(platGeo, platMat)\n plat.position.y = bumperH + bodyH + gapH + platH / 2\n plat.castShadow = true\n this.object3d.add(plat)\n\n // 수직 중앙 정렬\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n}\n\n/* ── 2D 렌더 ── */\n\nfunction renderVehicle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n fillStyle: string,\n platformColor: string\n) {\n var r = Math.min(w, h) * 0.1\n var bumperH = Math.max(3, h * 0.10)\n var platH = Math.max(4, h * 0.25)\n var platInset = Math.min(w, h) * 0.04\n\n // 하단 범퍼 밴드 (본체보다 약간 넓게)\n var bumperPad = Math.min(w, h) * 0.02\n ctx.fillStyle = BUMPER_COLOR\n ctx.beginPath()\n ctx.roundRect(x - bumperPad, y + h - bumperH, w + bumperPad * 2, bumperH, [0, 0, r, r])\n ctx.fill()\n\n // 본체 (둥근 사각형)\n ctx.fillStyle = fillStyle || DEFAULT_BODY_COLOR\n ctx.beginPath()\n ctx.roundRect(x, y + platH + 2, w, h - platH - bumperH - 2, r * 0.5)\n ctx.fill()\n\n ctx.strokeStyle = '#dddddd'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.roundRect(x, y + platH + 2, w, h - platH - bumperH - 2, r * 0.5)\n ctx.stroke()\n\n // 상단 플랫폼 (약간 안쪽)\n ctx.fillStyle = platformColor || DEFAULT_PLATFORM_COLOR\n ctx.beginPath()\n ctx.roundRect(x + platInset, y, w - platInset * 2, platH, [r, r, 0, 0])\n ctx.fill()\n}\n\n@sceneComponent('vehicle')\nexport class Vehicle extends RectPath(Shape) {\n buildRealObject(): RealObject | undefined {\n return new Vehicle3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n var fillStyle = this.getState('fillStyle')\n var platformColor = this.getState('platformColor')\n\n renderVehicle(ctx, left, top, width, height, fillStyle, platformColor)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n}\n"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/scene-visualizer",
3
3
  "description": "visualizer component for operato-scene",
4
4
  "author": "heartyoh",
5
- "version": "10.0.0-beta.10",
5
+ "version": "10.0.0-beta.14",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
@@ -63,5 +63,5 @@
63
63
  "prettier --write"
64
64
  ]
65
65
  },
66
- "gitHead": "c082970c7de1c9bb9f7a447d2723c0b06dfa8b37"
66
+ "gitHead": "3defb7207c541d87da3f5ebdd34f06d2e9e1cebb"
67
67
  }
@@ -1,8 +0,0 @@
1
- import { TemplateResult } from 'lit';
2
- import { OxPropertyEditor, PropertySpec } from '@operato/property-editor';
3
- export default class StockerPortsEditor extends OxPropertyEditor {
4
- static styles: import("lit").CSSResult[];
5
- editorTemplate(value: any, _spec: PropertySpec): TemplateResult;
6
- private _set;
7
- private _applyPorts;
8
- }