Updating sym.w/h mid-drag shifted the rotation center used by toSymbolLocal, causing waypoints to jump. Now recalcEpcBounds only runs on mouseup, keeping the coordinate transform stable. Also removed the endpoint slide constraint that was causing instability due to using the moving position as direction source. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SCADA Device Layout Tool
Interactive canvas-based tool for designing SCADA device layouts. Built with SvelteKit + Svelte 5 + TypeScript + HTML5 Canvas.
Project Structure
scada_device_layout/
├── projectes/ # Project data (outside svelte-app)
│ └── CDW5/
│ └── excel/
│ ├── Amazon CDW5_Devices IO.xlsx
│ └── Amazon CDW5_IP Addresses_Local.xlsx
├── svelte-app/ # Main application
│ ├── src/
│ │ ├── lib/
│ │ │ ├── stores/layout.svelte.ts # Central state (LayoutStore)
│ │ │ ├── canvas/renderer.ts # Canvas draw loop (HiDPI-aware)
│ │ │ ├── canvas/interactions.ts # Mouse/keyboard, drag-and-drop
│ │ │ ├── canvas/collision.ts # AABB, spacing, snap
│ │ │ ├── symbols.ts # Symbol definitions, image cache
│ │ │ ├── symbol-config.ts # EPC, induction, photoeye, curve config
│ │ │ ├── pdf.ts # PDF background (pdfjs-dist v5)
│ │ │ ├── export.ts # SVG export, JSON save/load
│ │ │ └── projects.ts # Project/MCM discovery
│ │ ├── components/
│ │ │ ├── Canvas.svelte # Canvas + PDF background + context menu
│ │ │ ├── Toolbar.svelte # Left panel: project/MCM, settings, palette
│ │ │ ├── Palette.svelte # Symbol palette (drag to place)
│ │ │ └── DeviceDock.svelte # Right panel: device list from Excel
│ │ └── routes/+page.svelte # App layout
│ ├── static/
│ │ ├── symbols/ # SVG symbol files
│ │ └── projectes/ # Build-generated manifests + MCM placeholders
│ │ ├── manifest.json # Project/MCM manifest (auto-generated)
│ │ └── devices-manifest.json # Device list per MCM (auto-generated)
│ └── vite.config.ts # Vite plugins for manifest generation
Setup & Run
cd svelte-app
npm install
npm run dev # Dev server at http://localhost:5173
Build & Preview
npm run build # Production build to build/
npm run preview # Preview at http://localhost:4173
Excel Data
Place Excel files in projectes/{PROJECT}/excel/:
- Devices IO (
*Devices IO*.xlsx): Contains MCM sheets with device assignments. Columns: Controller name, Signal type, Address name, Assigned device, Description. - IP Addresses (
*IP Address*.xlsx): Network structure sheets with VFDs, FIOMs, DPMs.
The Vite build plugin auto-parses these into devices-manifest.json at build time.
Features
- Canvas rendering with
requestAnimationFrameloop and dirty flag - HiDPI zoom — canvas buffer scales to
DPR x zoomLevel(capped at 4x) for crisp rendering at any zoom - Configurable canvas size — W/H adjustable in Settings, saved per MCM
- Symbol palette (left dock) — drag generic symbols onto canvas
- Device dock (right dock) — per-MCM device list parsed from Excel, grouped by symbol type. Drag to place with auto-labeling. Placed devices disappear from the list; deleting from canvas restores them.
- 3-slice photoeye resize — extending PEs stretches only the middle beam, left/right caps stay fixed
- PDF background — load reference PDFs behind the canvas, adjustable scale/position
- SVG export with Inkscape-compatible labels
- JSON save/load — layout state persisted to localStorage per project/MCM
- Undo (Ctrl+Z), multi-select, snap-to-grid, collision detection
Symbol Types
Conveyance: Conveyor, Chute, Tipper, Curved Conveyor/Chute (30/45/60/90), Spur, Extendo, Induction, Diverter I/O: FIO/SIO/FIOH Sensors: Photoeye, Pressure Sensor Controls: Jam Reset, Start, Start Stop, Chute Enable, Package Release, Beacon, Solenoid Other: PDP, DPM, MCM, EPC, IP Camera
Device Classification (from Excel)
| Excel suffix | Symbol | Notes |
|---|---|---|
| TPE, LPE, JPE, FPE, BDS, TS | Photoeye | All PE variants |
| EPC | EPC | 2 channels per EPC, only 1 symbol |
| JR_PB | Jam Reset | _LT variants skipped (indicator light) |
| S_PB | Start | |
| SS_SPB / SS_STPB | Start Stop | |
| EN_PB | Chute Enable | |
| PR_PB | Package Release | |
| SOL | Solenoid | |
| DIV_LS | Diverter | |
| BCN | Beacon | All color variants consolidated |
| VFD (from IP sheet) | Conveyor | VFD = conveyor drive |
| FIO*, SIO*, FIOM, FIOH | FIO/SIO/FIOH | From both controller and device columns |
| DPM | DPM | From IP sheet |
| PDP CB + PMM | PDP | Consolidated per PDP unit |
| PS | Pressure Sensor |
Skipped: ENSH/ENW (encoders), VFD_DISC (disconnect), _LT (lights), EPC 2nd channel, ESTOP, SCALE, STO, PRX, LRPE.
Description
Languages
TypeScript
73.4%
Svelte
13.3%
JavaScript
10.6%
CSS
1.7%
HTML
1%