9.0 KiB
9.0 KiB
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
npm install
npx playwright install chromium
2. Start Development Server
npm run server
# or
python3 -m http.server 8889
3. Generate Screenshots
# 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.pngsrc/ui_hybrid_5.html→src_ui_hybrid_5.html.pngmapbox_test/mapbox_globe_2/index.html→mapbox_test_mapbox_globe_2_index.html.png
Customizing Delays
Different demo types need different rendering times:
// 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
# 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
# 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
#!/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:
# 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:
# Start server in separate terminal
python3 -m http.server 8889
Playwright Not Installed
Problem: Error: Browser not found
Solution:
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:
# Regenerate specific screenshot
node generate_screenshots.js --single=threejs_viz/threejs_viz_1.html
# Or regenerate all
npm run screenshots
Advanced Usage
Single Screenshot
node generate_screenshots.js --single=path/to/demo.html
Custom Port
node generate_screenshots.js --port=3000
Category Filter
node generate_screenshots.js --category=threejs
Technical Details
Card HTML Structure
<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
// 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
// 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 for complete guide Project: README.md