324 lines
9.0 KiB
Markdown
324 lines
9.0 KiB
Markdown
# Dashboard Preview System
|
||
|
||
## Overview
|
||
|
||
The Infinite Agents dashboard now features a **hybrid preview system** combining static screenshots with live iframe previews for the best balance of performance and interactivity.
|
||
|
||
## Features
|
||
|
||
### 📸 Static Screenshot Thumbnails
|
||
- **200px preview** in every demo card
|
||
- **Zero performance overhead** (standard image loading)
|
||
- **Instant visual feedback** - no waiting
|
||
- **Fallback placeholder** if screenshot is missing
|
||
|
||
### 👁️ Live Iframe Preview on Hover
|
||
- **Hover for 800ms** to trigger live preview modal
|
||
- **Full-sized interactive demo** in modal (90vw × 80vh)
|
||
- **Only one iframe at a time** - efficient memory usage
|
||
- **Close with**: Escape key, backdrop click, or close button
|
||
|
||
## Quick Start
|
||
|
||
### 1. Install Dependencies
|
||
```bash
|
||
npm install
|
||
npx playwright install chromium
|
||
```
|
||
|
||
### 2. Start Development Server
|
||
```bash
|
||
npm run server
|
||
# or
|
||
python3 -m http.server 8889
|
||
```
|
||
|
||
### 3. Generate Screenshots
|
||
```bash
|
||
# All demos (~5-8 minutes for 107 demos)
|
||
npm run screenshots
|
||
|
||
# Or by category
|
||
npm run screenshots:threejs
|
||
npm run screenshots:sdg
|
||
npm run screenshots:ui
|
||
```
|
||
|
||
### 4. View Dashboard
|
||
Open http://localhost:8889/ in your browser.
|
||
|
||
## How It Works
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ User hovers over demo card (800ms) │
|
||
└───────────────┬─────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────┐
|
||
│ Modal appears with loading spinner │
|
||
└───────────────┬─────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────┐
|
||
│ Iframe loads demo (single instance) │
|
||
└───────────────┬─────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────┐
|
||
│ User can interact with live demo │
|
||
└───────────────┬─────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────┐
|
||
│ Close modal → iframe unloaded │
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
## Screenshot Generation
|
||
|
||
### Directory Structure
|
||
```
|
||
infinite-agents/
|
||
├── screenshots/ # Auto-generated
|
||
│ ├── threejs_viz_threejs_viz_1.html.png
|
||
│ ├── sdg_viz_sdg_viz_1.html.png
|
||
│ └── ...
|
||
├── generate_screenshots.js # Generator script
|
||
├── package.json # NPM scripts
|
||
└── index.html # Dashboard
|
||
```
|
||
|
||
### Filename Convention
|
||
Screenshots are named by replacing `/` with `_`:
|
||
- `threejs_viz/threejs_viz_1.html` → `threejs_viz_threejs_viz_1.html.png`
|
||
- `src/ui_hybrid_5.html` → `src_ui_hybrid_5.html.png`
|
||
- `mapbox_test/mapbox_globe_2/index.html` → `mapbox_test_mapbox_globe_2_index.html.png`
|
||
|
||
### Customizing Delays
|
||
|
||
Different demo types need different rendering times:
|
||
|
||
```javascript
|
||
// In generate_screenshots.js
|
||
const DEMO_CATEGORIES = {
|
||
threejs: { delay: 3000 }, // WebGL needs time
|
||
mapbox: { delay: 3000 }, // Tile loading
|
||
sdg: { delay: 2000 }, // D3 force simulation
|
||
d3: { delay: 1500 }, // SVG rendering
|
||
uiSingle: { delay: 800 }, // Static/simple
|
||
};
|
||
```
|
||
|
||
## NPM Scripts
|
||
|
||
```bash
|
||
# Dashboard
|
||
npm run dashboard # Regenerate index.html
|
||
npm run server # Start HTTP server
|
||
|
||
# Screenshots
|
||
npm run screenshots # All demos
|
||
npm run screenshots:threejs # Three.js only
|
||
npm run screenshots:sdg # SDG network only
|
||
npm run screenshots:d3 # D3 viz only
|
||
npm run screenshots:mapbox # Mapbox globes only
|
||
npm run screenshots:devtools # DevTools only
|
||
npm run screenshots:ui # UI components only
|
||
```
|
||
|
||
## Performance Comparison
|
||
|
||
### Before (No Previews)
|
||
- Initial load: **~100KB**
|
||
- Memory: **~50MB**
|
||
- First paint: **<100ms**
|
||
|
||
### After (Hybrid System)
|
||
- Initial load: **~2-3MB** (includes all screenshots)
|
||
- Memory: **~80MB** (base) + **40MB** per active iframe
|
||
- First paint: **~200ms**
|
||
- Screenshot cache: Cached after first load
|
||
- Iframe: Only 1 active at a time, unloaded on close
|
||
|
||
### With 107 Demos
|
||
- **15-20MB** total screenshots (compressed PNG)
|
||
- **Zero impact** when browsing (screenshots cached)
|
||
- **Minimal impact** when hovering (single iframe)
|
||
|
||
## Workflow Integration
|
||
|
||
### After Generating New Demos
|
||
```bash
|
||
# 1. Generate demos with infinite loop
|
||
/project:infinite-web specs/threejs_visualization_progressive.md threejs_viz 5
|
||
|
||
# 2. Update dashboard data
|
||
python3 generate_index.py
|
||
|
||
# 3. Generate screenshots for new demos
|
||
npm run screenshots:threejs
|
||
|
||
# 4. Refresh browser
|
||
```
|
||
|
||
### Automated Script
|
||
```bash
|
||
#!/bin/bash
|
||
# update_all.sh
|
||
|
||
echo "📊 Updating dashboard..."
|
||
python3 generate_index.py
|
||
|
||
echo "📸 Generating screenshots..."
|
||
npm run screenshots
|
||
|
||
echo "✅ Complete! Refresh browser to see updates."
|
||
```
|
||
|
||
## Troubleshooting
|
||
|
||
### Screenshots Not Showing
|
||
**Problem:** Cards show 📸 placeholder icon
|
||
**Solution:**
|
||
```bash
|
||
# Check if screenshots directory exists
|
||
ls -la screenshots/
|
||
|
||
# Regenerate screenshots
|
||
npm run screenshots
|
||
```
|
||
|
||
### Server Not Running Error
|
||
**Problem:** `Server is not running on http://localhost:8889`
|
||
**Solution:**
|
||
```bash
|
||
# Start server in separate terminal
|
||
python3 -m http.server 8889
|
||
```
|
||
|
||
### Playwright Not Installed
|
||
**Problem:** `Error: Browser not found`
|
||
**Solution:**
|
||
```bash
|
||
npx playwright install chromium
|
||
```
|
||
|
||
### Modal Not Opening
|
||
**Problem:** Hover preview doesn't appear
|
||
**Solution:**
|
||
- Check browser console for errors
|
||
- Ensure you hover for 800ms (intentional delay)
|
||
- Try clicking card to open full demo
|
||
|
||
### Screenshots Look Wrong
|
||
**Problem:** Screenshots don't match current demo
|
||
**Solution:**
|
||
```bash
|
||
# Regenerate specific screenshot
|
||
node generate_screenshots.js --single=threejs_viz/threejs_viz_1.html
|
||
|
||
# Or regenerate all
|
||
npm run screenshots
|
||
```
|
||
|
||
## Advanced Usage
|
||
|
||
### Single Screenshot
|
||
```bash
|
||
node generate_screenshots.js --single=path/to/demo.html
|
||
```
|
||
|
||
### Custom Port
|
||
```bash
|
||
node generate_screenshots.js --port=3000
|
||
```
|
||
|
||
### Category Filter
|
||
```bash
|
||
node generate_screenshots.js --category=threejs
|
||
```
|
||
|
||
## Technical Details
|
||
|
||
### Card HTML Structure
|
||
```html
|
||
<div class="demo-card" data-path="threejs_viz/threejs_viz_1.html">
|
||
<div class="demo-screenshot">
|
||
<img src="screenshots/threejs_viz_threejs_viz_1.html.png"
|
||
onerror="this.style.display='none'">
|
||
<div class="demo-screenshot-placeholder">📸</div>
|
||
<div class="demo-screenshot-overlay">
|
||
<span>👁️ Hover to preview</span>
|
||
</div>
|
||
</div>
|
||
<!-- ... rest of card -->
|
||
</div>
|
||
```
|
||
|
||
### Modal System
|
||
```javascript
|
||
// Single reusable modal
|
||
const previewModal = document.querySelector('.preview-modal');
|
||
const previewIframe = document.querySelector('.preview-iframe');
|
||
|
||
// Hover handler (800ms delay)
|
||
card.addEventListener('mouseenter', () => {
|
||
hoverTimeout = setTimeout(() => {
|
||
showPreview(path, title);
|
||
}, 800);
|
||
});
|
||
|
||
// Unload iframe on close
|
||
function hidePreview() {
|
||
previewModal.classList.remove('visible');
|
||
setTimeout(() => {
|
||
previewIframe.src = ''; // Free memory
|
||
}, 300);
|
||
}
|
||
```
|
||
|
||
### Screenshot Capture
|
||
```javascript
|
||
// Playwright headless browser
|
||
const browser = await chromium.launch({ headless: true });
|
||
const page = await browser.newPage();
|
||
|
||
// Set viewport
|
||
await page.setViewportSize({ width: 1920, height: 1080 });
|
||
|
||
// Navigate and wait for render
|
||
await page.goto(url, { waitUntil: 'networkidle' });
|
||
await page.waitForTimeout(demo.delay);
|
||
|
||
// Capture viewport (not full page)
|
||
await page.screenshot({ path: screenshotPath, fullPage: false });
|
||
```
|
||
|
||
## Browser Compatibility
|
||
|
||
- **Chrome/Edge:** ✅ Full support
|
||
- **Firefox:** ✅ Full support
|
||
- **Safari:** ✅ Full support (backdrop-filter may vary)
|
||
|
||
## Future Improvements
|
||
|
||
- [ ] **WebP format** - 40% smaller file size
|
||
- [ ] **Lazy image loading** - Only load screenshots in viewport
|
||
- [ ] **Video previews** - For animated demos
|
||
- [ ] **Screenshot diff** - Only regenerate changed demos
|
||
- [ ] **Thumbnail optimization** - Lower resolution for cards
|
||
- [ ] **Progressive enhancement** - Work without screenshots
|
||
|
||
## Credits
|
||
|
||
Built for the **Infinite Agents** project using:
|
||
- Playwright for screenshot capture
|
||
- Vanilla JavaScript for modal system
|
||
- CSS Grid for responsive layout
|
||
|
||
---
|
||
|
||
**Documentation:** See [DASHBOARD.md](DASHBOARD.md) for complete guide
|
||
**Project:** [README.md](README.md)
|