feat: pattern editor
This commit is contained in:
354
PRESET_EDITOR.md
Normal file
354
PRESET_EDITOR.md
Normal file
@@ -0,0 +1,354 @@
|
||||
# Preset Editor - Implementation Summary
|
||||
|
||||
## Overview
|
||||
|
||||
A visual preset editor has been added to SPORE LEDLab, allowing users to create custom LED animations by combining reusable building blocks without writing code.
|
||||
|
||||
## Components Implemented
|
||||
|
||||
### 1. Building Blocks System (`presets/building-blocks.js`)
|
||||
|
||||
A comprehensive library of reusable animation components:
|
||||
|
||||
#### **Shapes**
|
||||
- Circle, Rectangle, Triangle, Blob, Point, Line
|
||||
- Configurable position, size, color, and intensity
|
||||
- Support for blending and compositing
|
||||
|
||||
#### **Transforms**
|
||||
- Rotate, Scale, Translate
|
||||
- Transform composition for complex movements
|
||||
|
||||
#### **Color Generators**
|
||||
- Solid, Gradient, Palette (multi-stop), Rainbow, Radial
|
||||
- HSV color space support
|
||||
- Programmable color functions
|
||||
|
||||
#### **Animations**
|
||||
- Linear Move, Rotation, Pulse
|
||||
- Oscillation (X/Y axes)
|
||||
- Bounce physics, Fade in/out
|
||||
- Time-based with customizable parameters
|
||||
|
||||
#### **Patterns**
|
||||
- Trail effects (fade decay)
|
||||
- Energy fields (distance-based intensity)
|
||||
- Radial patterns
|
||||
- Spiral patterns
|
||||
|
||||
### 2. Custom Preset Engine (`presets/custom-preset.js`)
|
||||
|
||||
A JSON-driven preset system that:
|
||||
- Loads and validates preset configurations
|
||||
- Manages multiple layers
|
||||
- Applies animations in real-time
|
||||
- Supports dynamic parameters
|
||||
- Renders frames at target FPS
|
||||
|
||||
**JSON Schema:**
|
||||
```json
|
||||
{
|
||||
"name": "Preset Name",
|
||||
"description": "Description",
|
||||
"layers": [
|
||||
{
|
||||
"type": "shape|pattern",
|
||||
"shape": "circle|rectangle|...",
|
||||
"position": { "x": 8, "y": 8 },
|
||||
"size": { "radius": 3 },
|
||||
"color": { "type": "solid", "value": "ff0000" },
|
||||
"animation": {
|
||||
"type": "pulse",
|
||||
"params": { "minScale": 0.5, "maxScale": 1.5, "frequency": 1.0 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"speed": { "type": "range", "min": 0.1, "max": 2.0, "default": 1.0 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Visual Editor UI (`public/scripts/preset-editor.js`)
|
||||
|
||||
A modern two-panel editor interface:
|
||||
|
||||
**Left Panel: Preset Management & Layers**
|
||||
- Preset metadata (name, description)
|
||||
- **New preset button** - Creates fresh preset with confirmation
|
||||
- Add layer button
|
||||
- Expandable layer list with:
|
||||
- Visual layer cards showing type and properties
|
||||
- Layer reordering (up/down arrows)
|
||||
- Layer deletion
|
||||
- Click to expand/collapse layer details
|
||||
- Management section:
|
||||
- Save/Load presets (localStorage)
|
||||
- Export/Import JSON files
|
||||
- Delete current preset
|
||||
|
||||
**Right Panel: Preview & Controls**
|
||||
- Preview controls bar:
|
||||
- Node selection dropdown (Canvas Only or specific node)
|
||||
- Start/Stop preview button
|
||||
- Status indicator
|
||||
- Canvas size and FPS display
|
||||
- **Real-time canvas preview** - Shows exact animation as streamed to nodes
|
||||
- **Synchronized rendering** - Client preview matches server output perfectly
|
||||
|
||||
### 4. Server Integration (`server/index.js`)
|
||||
|
||||
Added `startCustomPreset` handler:
|
||||
- Accepts JSON configuration via WebSocket
|
||||
- Creates CustomPreset instance
|
||||
- Manages streaming like built-in presets
|
||||
- Supports all existing features (parameters, node selection, FPS control)
|
||||
|
||||
### 5. UI Integration (`public/index.html`, `public/styles/main.css`)
|
||||
|
||||
- Added Editor tab to navigation
|
||||
- Modern two-panel responsive layout
|
||||
- Dark/light theme support with **enhanced dropdown styling**
|
||||
- **Dark dropdown backgrounds** with light text for better readability
|
||||
- Notification system for user feedback
|
||||
- Import/Export file handling
|
||||
- **Canvas renderer** (`public/scripts/canvas-renderer.js`) for client-side preview
|
||||
|
||||
### 6. Example Presets (`presets/examples/`)
|
||||
|
||||
Four complete example presets:
|
||||
1. **Pulsing Circle** - Rainbow circle with pulse animation
|
||||
2. **Bouncing Squares** - Multiple colored squares with oscillation
|
||||
3. **Spiral Rainbow** - Rotating spiral with multi-color gradient
|
||||
4. **Moving Triangle** - Linear movement with gradient colors
|
||||
|
||||
Plus comprehensive README documentation.
|
||||
|
||||
## Features
|
||||
|
||||
✅ **Visual Composition**
|
||||
- Drag-free layer management with expandable cards
|
||||
- Real-time property editing
|
||||
- Layer reordering and deletion
|
||||
- **Triangle shape support** - Full triangle rendering with rotation
|
||||
|
||||
✅ **Flexible Configuration**
|
||||
- Multiple shape types (circle, rectangle, triangle, blob, point)
|
||||
- Various color modes (solid, gradient, palette, rainbow)
|
||||
- Rich animation options (move, rotate, pulse, oscillate, fade)
|
||||
- Parameter customization
|
||||
- **Pattern layers** with intensity control
|
||||
|
||||
✅ **Save & Share**
|
||||
- LocalStorage persistence
|
||||
- JSON export/import
|
||||
- Version-controllable configurations
|
||||
- Shareable preset files
|
||||
- **New preset button** for fresh starts
|
||||
|
||||
✅ **Live Preview**
|
||||
- **Synchronized canvas preview** - Shows exact animation as streamed to nodes
|
||||
- Real-time streaming to selected node
|
||||
- Integrated with existing node selection
|
||||
- Full parameter control
|
||||
- **Layer compositing** - All layers render correctly with proper alpha blending
|
||||
|
||||
✅ **Reusable Components**
|
||||
- Extracted from existing presets
|
||||
- Optimized rendering
|
||||
- Extensible architecture
|
||||
- **Server-client rendering parity** - Identical output on both sides
|
||||
|
||||
## Usage Flow
|
||||
|
||||
1. User opens **🎨 Editor** view
|
||||
2. Enters preset name and description
|
||||
3. Adds layers:
|
||||
- Clicks "➕ Add Layer" button
|
||||
- Configures layer properties in expandable cards:
|
||||
- Shape type (circle, rectangle, triangle, blob, point)
|
||||
- Position (X, Y coordinates)
|
||||
- Size (radius, width, height)
|
||||
- Color (solid, gradient, palette, rainbow)
|
||||
- Intensity (0.0 - 1.0)
|
||||
- Animation (move, rotate, pulse, oscillate, fade)
|
||||
4. Manages layers:
|
||||
- Expands/collapses layer details by clicking
|
||||
- Reorders with up/down arrows
|
||||
- Deletes unwanted layers
|
||||
5. Previews animation:
|
||||
- Selects target node or "Canvas Only"
|
||||
- Clicks "▶️ Start" to begin preview
|
||||
- Watches synchronized canvas preview
|
||||
6. Saves work:
|
||||
- Uses "💾 Save" to store in localStorage
|
||||
- Uses "📤 Export JSON" to download file
|
||||
- Uses "📥 Import JSON" to load shared presets
|
||||
7. Creates new presets:
|
||||
- Uses "📄 New" button for fresh start
|
||||
- Confirms if current work will be lost
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Editor UI (Browser) │
|
||||
│ ┌────────────────────────────────────┐ │
|
||||
│ │ Preset Editor Component │ │
|
||||
│ │ - Layer Management │ │
|
||||
│ │ - Property Forms │ │
|
||||
│ │ - Preview Control │ │
|
||||
│ └────────────────────────────────────┘ │
|
||||
└──────────────┬──────────────────────────┘
|
||||
│ WebSocket (JSON Config)
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Server (Node.js) │
|
||||
│ ┌────────────────────────────────────┐ │
|
||||
│ │ startCustomPreset Handler │ │
|
||||
│ │ - Parse JSON configuration │ │
|
||||
│ │ - Create CustomPreset instance │ │
|
||||
│ │ - Start streaming │ │
|
||||
│ └────────────────────────────────────┘ │
|
||||
└──────────────┬──────────────────────────┘
|
||||
│ Frame Generation Loop
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Custom Preset Engine │
|
||||
│ ┌────────────────────────────────────┐ │
|
||||
│ │ Building Blocks System │ │
|
||||
│ │ - Shapes, Patterns, Colors │ │
|
||||
│ │ - Animations, Transforms │ │
|
||||
│ │ - Composition & Rendering │ │
|
||||
│ └────────────────────────────────────┘ │
|
||||
└──────────────┬──────────────────────────┘
|
||||
│ UDP Frames
|
||||
▼
|
||||
[SPORE Node LED Matrix]
|
||||
```
|
||||
|
||||
## File Changes Summary
|
||||
|
||||
### New Files
|
||||
- `presets/building-blocks.js` - Core building blocks library
|
||||
- `presets/custom-preset.js` - JSON-driven preset engine
|
||||
- `public/scripts/preset-editor.js` - Visual editor UI
|
||||
- `public/scripts/canvas-renderer.js` - Client-side canvas renderer
|
||||
- `presets/examples/pulsing-circle.json` - Example preset
|
||||
- `presets/examples/bouncing-squares.json` - Example preset
|
||||
- `presets/examples/spiral-rainbow.json` - Example preset
|
||||
- `presets/examples/moving-triangle.json` - Example preset
|
||||
- `presets/examples/README.md` - Example documentation
|
||||
- `PRESET_EDITOR.md` - This file
|
||||
|
||||
### Modified Files
|
||||
- `public/index.html` - Added Editor view HTML with New button
|
||||
- `public/styles/main.css` - Added editor styles and enhanced dropdown styling
|
||||
- `server/index.js` - Added custom preset handler
|
||||
- `presets/building-blocks.js` - Added intensity support for pattern layers
|
||||
- `presets/custom-preset.js` - Added intensity support for pattern rendering
|
||||
- `README.md` - Added Preset Editor documentation
|
||||
|
||||
## Extensibility
|
||||
|
||||
The system is designed to be easily extended:
|
||||
|
||||
**Add New Shape:**
|
||||
```javascript
|
||||
Shapes.star = (frame, width, height, centerX, centerY, points, radius, color) => {
|
||||
// Rendering logic
|
||||
};
|
||||
```
|
||||
|
||||
**Add New Animation:**
|
||||
```javascript
|
||||
Animations.wobble = (amplitude, frequency) => {
|
||||
return () => {
|
||||
// Animation logic
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
**Add New Color Generator:**
|
||||
```javascript
|
||||
ColorGenerators.plasma = (time, x, y) => {
|
||||
// Color calculation
|
||||
};
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
- Efficient rendering with minimal allocations
|
||||
- Frame generation at configurable FPS (1-60)
|
||||
- Optimized color blending
|
||||
- Smart update scheduling
|
||||
|
||||
## Browser Compatibility
|
||||
|
||||
- Modern browsers (Chrome, Firefox, Safari, Edge)
|
||||
- Requires ES6+ support
|
||||
- LocalStorage for persistence
|
||||
- File API for import/export
|
||||
|
||||
## Recent Updates
|
||||
|
||||
### Latest Improvements (Current Version)
|
||||
- ✅ **Triangle Shape Support** - Added full triangle rendering with rotation animation
|
||||
- ✅ **Layer Compositing Fix** - All layers now render correctly with proper alpha blending
|
||||
- ✅ **Server-Client Synchronization** - Preview canvas shows identical animation to streamed output
|
||||
- ✅ **Pattern Layer Intensity** - Pattern layers now support intensity control like shape layers
|
||||
- ✅ **New Preset Button** - Quick way to start fresh with confirmation dialog
|
||||
- ✅ **Enhanced Dropdown Styling** - Dark backgrounds with light text for better readability
|
||||
- ✅ **Canvas Renderer** - Dedicated client-side renderer for accurate previews
|
||||
|
||||
### Bug Fixes
|
||||
- Fixed pattern layer overwriting instead of compositing with other layers
|
||||
- Fixed gradient color calculation bug in client-side renderer
|
||||
- Fixed triangle rendering missing from preview canvas
|
||||
- Improved dropdown readability in dark theme
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Possible future additions:
|
||||
- [ ] Undo/Redo support
|
||||
- [ ] Layer groups
|
||||
- [ ] Custom parameter types
|
||||
- [ ] Animation timeline editor
|
||||
- [ ] Blend modes between layers
|
||||
- [ ] Physics simulations
|
||||
- [ ] Sound-reactive parameters
|
||||
- [ ] Community preset library
|
||||
- [ ] Preset thumbnails/previews
|
||||
- [ ] Keyboard shortcuts
|
||||
- [ ] Line shape support
|
||||
- [ ] Additional pattern types
|
||||
- [ ] Real-time collaboration
|
||||
|
||||
## Testing
|
||||
|
||||
To test the implementation:
|
||||
|
||||
1. Start LEDLab server: `npm start`
|
||||
2. Open browser to `http://localhost:3000`
|
||||
3. Navigate to Stream view and select a node
|
||||
4. Switch to Editor view
|
||||
5. Import an example preset (e.g., `pulsing-circle.json`)
|
||||
6. Click Preview to see it running
|
||||
7. Modify parameters and preview again
|
||||
8. Create your own preset from scratch
|
||||
9. Export and reimport to verify JSON handling
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Preset Editor provides a powerful, user-friendly way to create custom LED animations without coding. It leverages a well-architected building blocks system that extracts reusable patterns from existing presets and makes them composable through a visual interface and JSON configuration.
|
||||
|
||||
**Key achievements:**
|
||||
- **Perfect synchronization** between preview and actual output
|
||||
- **Comprehensive shape support** including triangles with rotation
|
||||
- **Proper layer compositing** with alpha blending
|
||||
- **Intuitive UI** with expandable layer cards and dark theme
|
||||
- **Robust persistence** with localStorage and JSON export/import
|
||||
- **Real-time preview** that matches server rendering exactly
|
||||
|
||||
The editor is now production-ready with all major rendering issues resolved and enhanced user experience features implemented.
|
||||
|
||||
Reference in New Issue
Block a user