Transform your ideas into stunning visual presentations with drag-and-drop simplicity and professional polish.
Showcase is a desktop-class web application that lets you create beautiful, interactive presentations by simply dragging images and videos onto an infinite canvas. No slides, no templates, no constraints—just pure creative freedom.
| Feature | Traditional Tools | Showcase |
|---|---|---|
| 📊 Layout | Fixed slides | Infinite canvas with zoom & pan |
| 🎯 Arrangement | Manual positioning | Smart layouts (Circle, Grid, Snake, etc.) |
| 🎨 Backgrounds | Limited options | Color, Gradient, or Custom Images |
| 💾 Storage | File-based | Auto-save with unlimited capacity |
| ⚡ Performance | Can lag with media | Smooth 60fps with hardware acceleration |
| 🎬 Animations | Basic transitions | Buttery-smooth Framer Motion |
- Node.js 16+ installed
- Modern web browser (Chrome, Firefox, Safari, Edge)
# 1️⃣ Install dependencies
npm install
# 2️⃣ Start the development server
npm run dev
# 3️⃣ Open your browser
# Visit http://localhost:3003 (or the port shown in terminal)That's it! You're ready to create. 🎉
- Click the "📎 Add Media" button in the top toolbar
- Select images or videos from your computer (you can select multiple!)
- Choose orientation:
- Landscape (16:9) - Great for photos and videos
- Portrait (9:16) - Perfect for mobile screenshots
- Watch your media appear on the canvas!
Create beautiful text overlays with full typography control:
To Add Text:
- Click the "✍️ Expression" button in the toolbar
- Customize your text properties:
- Font Family - Choose from 10+ fonts with live preview
- Font Size - Select from 12px to 128px (16 preset sizes)
- Color - Pick from 20 preset colors or use custom color picker
- Click "Add Text Field" to place it on the canvas
To Edit Existing Text:
- Single-click any text field → Edit the text content directly (type immediately)
- Double-click text field → Opens properties menu for font/size/color changes
- Drag to reposition (smooth, snappy movement like cards)
- Delete using the ❌ button (appears on hover)
Font Options:
- Sans-serif (default), Serif, Monospace
- Cursive, Fantasy, Arial, Verdana
- Helvetica, Times New Roman, Comic Sans
Color Presets Include:
- Basic colors: White, Black, Red, Green, Blue
- Vibrant colors: Yellow, Magenta, Cyan, Orange, Purple
- Pastels: Soft pink, Turquoise, Sky blue, Golden yellow, Deep purple
- Plus custom hex/RGB input for unlimited possibilities!
- Drag cards anywhere on the canvas
- Resize cards by dragging the bottom-right corner
- Delete cards by clicking the ❌ button (appears on hover)
Click any layout button in the toolbar to instantly organize your cards:
| Layout | Icon | Best For | Visual Pattern | Guide Markers |
|---|---|---|---|---|
| Circle | ⭕ | Highlighting central theme | Cards arranged in a perfect circle | Center dot |
| Grid | ▦ | Galleries & portfolios | Organized rows and columns | Rectangle frames |
| Line | ━ | Timelines & sequences | Horizontal alignment | Start ● → End ✕ |
| Curve | 〰️ | Dynamic presentations | Smooth sine wave | Start ● → End ✕ |
| Snake | 〰 | Creative layouts | Multi-wave S-pattern | Start ● → End ✕ |
💡 Pro Tip: Line, Curve, and Snake layouts include pirate treasure map-style markers - a circle (●) marks the start and an X (✕) marks the end!
🎯 Layout Persistence: Your selected layout and customizations are automatically saved and will reappear on reload!
When you apply a layout, visual guides appear on your canvas.
To customize guides:
- Click on any guide (circle, line, etc.)
- A customization menu appears with:
- Thickness slider - Drag left/right to adjust (1-20px)
- 8 preset colors - Click to select
- Custom color input - Enter hex (#FF00FF) or rgb/rgba values
- Changes apply instantly!
Click the 🎨 button (positioned to the left of the minimap) in the bottom-right corner to access:
- Solid background color
- Color picker + hex code input
- Perfect for clean, professional looks
- Two-color linear gradients
- Adjustable angle (0-360°)
- Live preview before applying
- Great for modern, eye-catching backgrounds
- Upload custom background images
- Overlay opacity slider (0-100%) - Darken/lighten image for better card visibility
- Background blur slider (0-20px) - Apply blur effect to background while keeping cards sharp
- Smart layering - opacity and blur only affect background, not your content
- Remove or replace anytime
- Ideal for branding and thematic presentations
💡 Pro Tip: Combine opacity and blur for a beautiful depth-of-field effect that makes your cards pop!
| Button | Function | Shortcut |
|---|---|---|
| 👆/✋ | Toggle Cursor/Hand mode | - |
| ➕ | Zoom in | Scroll up |
| ➖ | Zoom out | Scroll down |
| 🎯 | Reset view to 100% | - |
Cursor Mode (👆)
- Drag cards to reposition
- Resize and delete cards
- Click empty space to pan canvas
Hand Mode (✋)
- Entire canvas becomes draggable
- Perfect for exploring large presentations
- Cards are locked (can't accidentally move them)
- Bottom-left corner shows entire canvas overview
- Blue rectangle = your current view
- Click/drag inside minimap to jump to any area
- Automatically scales with zoom level
Your work is automatically saved every second to your browser's storage (IndexedDB). No "Save" button needed—just create!
| Button | Format | What's Included | Best For |
|---|---|---|---|
| 💾 Save | JSON | Embedded images & metadata | Sharing & backup |
| 📦 Export | ZIP | Images embedded, videos external | Large presentations |
| 📂 Load | JSON/ZIP | Everything restored | Continuing previous work |
Export includes:
- All cards with positions and sizes
- All text fields with content, fonts, sizes, and colors
- Background settings (color/gradient/image with opacity and blur)
- Active layout and guide customizations (color, stroke width)
- Zoom and pan state
- All visual states persist across sessions
Showcase uses a sophisticated layering system for optimal visual hierarchy:
- Layer 0: Background image or color (bottom)
- Layer 1: Opacity overlay with optional blur
- Layer 2: Layout guides (circles, lines, curves, grids, snakes)
- Layer 3: Media cards (your content)
- Layer 4: UI controls (top)
This ensures your content is always sharp and visible, even with blur effects!
Ctrl/Cmd + Z- UndoCtrl/Cmd + Y- RedoSpace + Drag- Pan canvasDelete- Remove selected card
✅ DO:
- Use compressed images (WebP, optimized JPG)
- Keep videos under 100MB each
- Close minimap if working with 100+ cards
- Uncompressed PNG files (use JPG instead)
- 4K videos (1080p is plenty)
- Loading 500+ cards at once
- Add company logo as background image
- Arrange product photos in grid layout
- Adjust overlay opacity for professional look
- Export as ZIP for client delivery
- Upload artwork in portrait orientation
- Use snake layout for dynamic arrangement
- Customize guide colors to match brand
- Enable hand mode for smooth navigation
- Add infographic images
- Arrange in circle around central concept
- Use gradient background for visual interest
- Share JSON file with students
- Import vacation photos
- Create curved timeline arrangement
- Add background image of destination
- Navigate with minimap for storytelling
showcase/
├── 📁 src/
│ ├── 📁 components/ # React UI Components
│ │ ├── Card.jsx # Draggable media cards
│ │ ├── Playfield.jsx # Main infinite canvas
│ │ ├── Toolbar.jsx # Top menu bar
│ │ ├── VerticalToolbar.jsx # Zoom controls
│ │ ├── Minimap.jsx # Navigation overview
│ │ ├── LayoutGuides.jsx # Visual layout helpers
│ │ ├── LayoutCustomizationMenu.jsx
│ │ ├── BackgroundMenu.jsx # Background settings panel
│ │ └── ... # More components
│ │
│ ├── 📁 store/
│ │ └── useStore.js # Zustand state management
│ │
│ ├── 📁 utils/
│ │ ├── storage.js # IndexedDB operations
│ │ └── export.js # Import/export utilities
│ │
│ ├── App.jsx # Main application
│ ├── App.css # Global styles
│ └── main.jsx # Entry point
│
├── index.html # HTML template
├── vite.config.js # Vite configuration
├── package.json # Dependencies
└── README.md # You are here!
Showcase is built with cutting-edge web technologies for maximum performance:
- React 19 - Latest UI library with concurrent features
- Vite - Lightning-fast bundler (10x faster than Webpack)
- Zustand - Tiny (2.9KB) state management
- Framer Motion - Smooth 60fps animations
- @dnd-kit - Hardware-accelerated drag & drop
- CSS Transforms - GPU-optimized rendering
- IndexedDB (idb) - Unlimited browser storage
- JSZip - Client-side ZIP creation
- Lodash - Throttle/debounce utilities
| Technology | Benefit |
|---|---|
| React 19 | Virtual DOM prevents expensive reflows |
| Vite | Instant hot module reload (HMR) |
| Zustand | No boilerplate, just set() and get() |
| Framer Motion | Spring physics for natural animations |
| @dnd-kit | Touch & pointer events, accessibility |
| IndexedDB | Store 100s of images without limits |
| Metric | v1.0 (Vanilla JS) | v2.0 (React) | Improvement |
|---|---|---|---|
| Initial Load | ~50ms | ~200ms | Acceptable trade-off |
| Drag Smoothness | Laggy @ 10+ cards | Smooth @ 50+ cards | 5x better |
| Save Operation | Blocks UI | Background | Instant |
| Animation FPS | 20-30 fps | 60 fps | 2-3x smoother |
| Storage Limit | 5-10 MB | Unlimited* | ∞ better |
| Cards Supported | ~50 | 500+ | 10x more |
*Subject to browser quota (typically several GB)
# Vite automatically finds the next available port
# Check terminal output for actual port (3001, 3002, etc.)// Open browser console and check quota:
const info = await navigator.storage.estimate();
console.log('Used:', (info.usage / 1024 / 1024).toFixed(2), 'MB');
console.log('Available:', (info.quota / 1024 / 1024).toFixed(2), 'MB');Solution: Export your work as ZIP, clear browser data, then reload.
- Check Chrome DevTools → Performance tab
- Reduce number of cards (try exporting old ones)
- Close other browser tabs
- Try incognito mode (extensions can slow things down)
- Click 🎨 button (left of minimap) → Image mode
- Check if image uploaded successfully (preview thumbnail shows)
- Adjust overlay opacity slider (try reducing it to 0% temporarily)
- Verify blur isn't too high (reset to 0px if needed)
- Try a different image format (JPG works best)
- Ensure you've clicked a layout button (Circle, Grid, etc.)
- Check that you have at least 1 card on canvas
- Layout guides persist - reload the page to restore saved layouts
- Click guide → customize color to contrast background
- Increase stroke width slider (try 8-10px for better visibility)
This shouldn't happen! If it does:
- Check z-index is correct (overlay should be below cards)
- Refresh the page to reset layering
- Report as a bug - this violates the layering system
- ✍️ Text fields with full typography control
- 🎨 20 color presets + custom color picker
- 📝 Click-to-edit text properties
- 🔤 10+ font families with live preview
- 🎨 Background opacity control (0-100%)
- 🌫️ Background blur effect (0-20px)
- 🗺️ Pirate treasure map markers (● start, ✕ end)
- 💾 Layout guide persistence
- 🎯 Smart z-index layering system
- 📱 Responsive design (smartphone to desktop)
- 🔄 Undo/Redo functionality
- 🎨 Text background/border options
- ✏️ Drawing tools & annotations
- 🎭 Presentation mode with transitions
- ⌨️ Full keyboard shortcut support
- 📱 Touch gesture support (pinch, swipe)
- 👥 Real-time collaboration
- ☁️ Cloud storage integration
- 📄 Export to PDF/PowerPoint
- 🎨 Templates library
- 🔗 Shareable presentation links
- 🌙 Dark mode UI
Want to contribute? Check out our issues or suggest features!
- React Official Docs - Best place to start
- Vite Guide - Understand the build tool
- Add a new layout algorithm → Edit
src/store/useStore.js - Create custom card types → See
src/components/Card.jsx - Add keyboard shortcuts → Check
src/components/Playfield.jsx
MIT License - Free to use and modify!
✅ Use for personal projects ✅ Use for commercial products ✅ Modify and redistribute ✅ No attribution required (but appreciated!)
- Author: Yassine Boumiza
- Original Concept: Showcase v1.0 (Vanilla JavaScript)
- v2.0 Rebuild: React 19 + Modern Stack
- Icons: Unicode emoji (no dependencies!)
- React Team - For the amazing framework
- Vercel - For Vite
- pmndrs - For Zustand
- Framer - For Framer Motion
- Clauderic - For @dnd-kit
- You, for using Showcase! 🎉
- Contributors who report bugs and suggest features
- The open-source community
We welcome contributions! Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
- 🐛 Bug fixes
- ✨ New features
- 📚 Documentation improvements
- 🎨 UI/UX enhancements
- 🧪 Test coverage
- ♿ Accessibility improvements
- 📖 Documentation: You're reading it!
- 🐛 Bug Reports: GitHub Issues
- 💡 Feature Requests: GitHub Discussions
- ⭐ Star the repo to get notified of updates
- 👀 Watch for new releases
- 🍴 Fork to create your own version
npm run devOpen http://localhost:3003 and start building something amazing!