Phases 7-10: Complete remaining features and optimizations

Phase 7.2 - Debounce undo/redo history:
- Add 300ms debounce timer for rapid drag/transform changes
- Commit history on dragEnd/transformEnd events only
- Prevents history bloat during continuous interactions

Phase 8.3 - Template-aware export:
- Render template background layer first
- Apply slot crop regions for image elements
- Render template overlay layer last
- Support nonPrintable flag for guides/watermarks

Phase 9 - PWA icons:
- Add pwa-192x192.svg and pwa-512x512.svg icons
- Update vite.config.js manifest configuration

Phase 10.3 - Performance optimizations:
- Add React.memo to canvas components (ImageElement, TextElement, DesignCanvas)
- Add React.memo to panel components (LayersPanel, PropertiesPanel)
- Prevent unnecessary re-renders during canvas interactions

Phase 10.6 - Template documentation:
- Document template JSON schema in docs/template-schema.md
- Include element properties, slot definitions, and examples
- Describe background/overlay layer structure
This commit is contained in:
Khalid A
2026-04-21 21:50:33 -05:00
parent a02f020d4c
commit 4ca7910465
14 changed files with 465 additions and 93 deletions

239
docs/template-schema.md Normal file
View File

@@ -0,0 +1,239 @@
# Template JSON Schema
This document describes the template structure for creating custom t-shirt design templates.
## Template Structure
```json
{
"id": "string (unique identifier)",
"name": "string (display name)",
"category": "string (Sports|Music|Quotes|Animals|Abstract|Vintage|Nature|Tech)",
"description": "string (short description)",
"elements": [
{
"type": "text" | "image",
"text": "string (for text elements only)",
"x": "number (x position in canvas units)",
"y": "number (y position in canvas units)",
"fontSize": "number (for text elements)",
"fontFamily": "string (Google Font name)",
"fill": "string (hex color)",
"rotation": "number (degrees, -180 to 180)",
"width": "number (for image elements)",
"height": "number (for image elements)",
"src": "string (image URL or path)"
}
]
}
```
## Element Properties
### Text Element
| Property | Type | Required | Description |
|------------|--------|----------|---------------------------------------|
| `type` | string | Yes | Must be `"text"` |
| `text` | string | Yes | The text content to display |
| `x` | number | Yes | X position on canvas (0-300) |
| `y` | number | Yes | Y position on canvas (0-300) |
| `fontSize` | number | Yes | Font size in pixels (12-120) |
| `fontFamily`| string| No | Google Font name (default: "DM Sans") |
| `fill` | string | No | Hex color (default: "#0f172a") |
| `rotation` | number | No | Rotation in degrees (default: 0) |
### Image Element
| Property | Type | Required | Description |
|------------|--------|----------|---------------------------------------|
| `type` | string | Yes | Must be `"image"` |
| `src` | string | Yes | Image URL or server path |
| `x` | number | Yes | X position on canvas (0-300) |
| `y` | number | Yes | Y position on canvas (0-300) |
| `width` | number | Yes | Width in canvas units (min: 20) |
| `height` | number | Yes | Height in canvas units (min: 20) |
| `rotation` | number | No | Rotation in degrees (default: 0) |
## Advanced Template Features
### Template with Background and Overlay
For templates that include background images and overlay elements:
```json
{
"id": "team-sport",
"name": "Team Sport",
"category": "Sports",
"description": "Classic team jersey with number and text",
"background": {
"type": "color" | "image",
"color": "string (hex, if type is color)",
"src": "string (URL/path, if type is image)"
},
"overlay": [
{
"type": "text" | "image",
"nonPrintable": false,
"...": "same properties as regular elements"
}
],
"elements": [...]
}
```
### Slot-Based Templates
For templates with image slots (auto-crop regions):
```json
{
"id": "classic-tee-front",
"name": "Classic Tee - Front",
"slots": [
{
"id": "chest-logo",
"bounds": { "x": 100, "y": 80, "width": 100, "height": 100 },
"aspectRatio": 1.0,
"label": "Chest Logo"
},
{
"id": "sleeve-left",
"bounds": { "x": 20, "y": 100, "width": 60, "height": 60 },
"aspectRatio": 1.0,
"label": "Left Sleeve"
}
],
"elements": []
}
```
### Slot Crop Region
When an image is assigned to a slot, the crop property is applied:
```json
{
"type": "image",
"src": "/uploads/image.png",
"x": 100,
"y": 80,
"width": 100,
"height": 100,
"crop": {
"sx": 0,
"sy": 0,
"sWidth": 500,
"sHeight": 500
}
}
```
| Property | Type | Description |
|-----------|--------|--------------------------------------|
| `sx` | number | Source x coordinate for crop |
| `sy` | number | Source y coordinate for crop |
| `sWidth` | number | Source width for crop |
| `sHeight` | number | Source height for crop |
## Non-Printable Elements
Elements can be marked as non-printable to exclude them from export:
```json
{
"type": "text",
"text": "Guide Text",
"nonPrintable": true,
"x": 150,
"y": 150,
"fontSize": 12,
"fill": "#cccccc"
}
```
## Example Templates
### Minimal Quote Template
```json
{
"id": "minimal-quote",
"name": "Minimal Quote",
"category": "Quotes",
"description": "Simple centered quote design",
"elements": [
{
"type": "text",
"text": "\"Be the change\"",
"x": 150,
"y": 130,
"fontSize": 24,
"fontFamily": "Georgia",
"fill": "#1e293b",
"rotation": 0
},
{
"type": "text",
"text": "you wish to see",
"x": 150,
"y": 160,
"fontSize": 18,
"fontFamily": "Arial",
"fill": "#64748b",
"rotation": 0
}
]
}
```
### Team Sport Template
```json
{
"id": "team-sport",
"name": "Team Sport",
"category": "Sports",
"description": "Classic team jersey with number and text",
"elements": [
{
"type": "text",
"text": "TEAM NAME",
"x": 75,
"y": 80,
"fontSize": 28,
"fontFamily": "Impact",
"fill": "#ffffff",
"rotation": 0
},
{
"type": "text",
"text": "23",
"x": 150,
"y": 150,
"fontSize": 72,
"fontFamily": "Impact",
"fill": "#ffffff",
"rotation": 0
}
]
}
```
## Canvas Coordinate System
- Canvas size: 300x300 units (preview)
- Export size: 4500x4500 pixels (300 DPI, 15"x15")
- Scale factor: 15x (export / preview)
- Origin (0,0): Top-left corner
- X increases: Left to right
- Y increases: Top to bottom
## Best Practices
1. **Keep text readable**: Use font sizes between 18-72px for main text
2. **Respect print area**: Keep elements within 0-300 canvas bounds
3. **Use contrasting colors**: Ensure text is visible on shirt colors
4. **Test at export size**: Verify designs look good at 4500x4500px
5. **Limit elements**: 5-10 elements maximum for performance