An AI-powered infinite canvas web application for image generation and creative workflows. Built with React, TypeScript, and tldraw.
PopArt combines an infinite canvas experience with AI image generation capabilities. Create, organize, and iterate on AI-generated images in a fluid, visual workspace.
- Infinite Canvas: Smooth pan and zoom navigation powered by tldraw
- Drag & Drop: Import local images directly onto the canvas
- Image Management: Select, move, resize, and rotate images freely
- Auto-persistence: Canvas state automatically saved to localStorage
- Multiple Models: Support for Gemini (Nano Banana, Nano Banana Pro) and Seedream (4.0, 4.5) models
- Text-to-Image: Generate images from text prompts
- Image-to-Image: Use existing images as references for generation
- Configurable Output: Choose aspect ratios (1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3) and quality (1K, 2K, 4K)
- Concurrent Generation: Generate up to 5 images simultaneously
- Smart Placement: New images automatically positioned to avoid overlaps
- Floating Toolbar: Quick actions (copy, download, info) for selected images
- Bottom Prompt Panel: Centered input panel with model/size selection
- Image Metadata: View generation details including prompt, model, and timestamp
- Onboarding Guide: First-time user tutorial with example content
| Category | Technology |
|---|---|
| Framework | React 18 + TypeScript |
| Canvas | tldraw v2 |
| State Management | Zustand |
| Styling | TailwindCSS |
| Build Tool | Vite |
| Icons | Phosphor Icons |
| AI Integration | OpenAI-compatible API (Gemini, Seedream) |
- Node.js 18+
- npm or pnpm
- API Key for image generation
- Clone the repository
git clone <your-repo-url>
cd popart- Install dependencies
npm install- Start the development server
npm run devThe app will be available at http://localhost:5173
- Configure your API key via the settings modal (gear icon at bottom right)
You can also configure API keys via environment variables:
# .env.local
VITE_API_KEY=your_api_key_here
VITE_REPLICATE_API_KEY=your_replicate_key_here # For image upscaling
VITE_REMOVE_BG_API_KEY=your_remove_bg_key_here # For background removalpopart/
├── src/
│ ├── components/
│ │ ├── Canvas/
│ │ │ └── TldrawCanvas.tsx # Main canvas component
│ │ └── UI/
│ │ ├── BottomPromptPanel.tsx # AI generation input
│ │ ├── FloatingToolbar.tsx # Selected image actions
│ │ ├── GeneratingOverlay.tsx # Loading state overlay
│ │ └── SettingsModal.tsx # API key configuration
│ ├── services/
│ │ └── ai/
│ │ └── imageGeneration.ts # AI API integration
│ ├── stores/
│ │ └── useAIStore.ts # Zustand store for AI state
│ ├── hooks/
│ │ └── useKeyboardShortcuts.ts # Keyboard shortcut handlers
│ ├── utils/
│ │ ├── imageAssets.ts # Image asset management
│ │ ├── apiKeyStorage.ts # API key persistence
│ │ └── onboarding.ts # First-time user guide
│ ├── types/
│ │ └── index.ts # TypeScript definitions
│ ├── App.tsx
│ ├── main.tsx
│ └── index.css
├── public/
├── index.html
├── vite.config.ts
├── tailwind.config.js
├── tsconfig.json
└── package.json
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
TypeScript check + production build |
npm run preview |
Preview production build |
npm run lint |
Run ESLint |
- Configure API Key: Click the gear icon at bottom right and enter your API key
- Enter Prompt: Type your image description in the bottom panel
- Select Model: Choose between Gemini or Seedream models
- Choose Settings: Select aspect ratio and quality
- Generate: Press Enter or click the arrow button
- Select one or more images on the canvas
- Enter a prompt describing the desired changes
- Generate - the selected images will be used as references
| Shortcut | Action |
|---|---|
Enter |
Generate image from prompt |
Cmd/Ctrl + D |
Duplicate selected images |
Cmd/Ctrl + +/- |
Zoom in/out |
Cmd/Ctrl + 0 |
Reset zoom |
Delete/Backspace |
Delete selected |
- User enters prompt in
BottomPromptPanel useAIStore.generateImage()callsimageGeneration.ts- Placeholder shape created on canvas during generation
- API response (base64) converted to data URL
- Placeholder updated with actual image via
updatePlaceholderWithImage()
The app uses tldraw's TLComponents system to inject custom UI overlays:
- Custom
InFrontOfTheCanvascomponent for floating UI elements - Asset store for managing image data URLs
- Editor hooks for canvas manipulation
- Project infrastructure (Vite, React, TypeScript, TailwindCSS)
- Infinite canvas with tldraw
- AI image generation (Gemini & Seedream)
- Image-to-image generation
- Floating toolbar with image actions
- Image upscaling (Real-ESRGAN via Replicate)
- Background removal (remove.bg API)
- Performance optimization for large canvases
- Export/import canvas functionality
MIT
- tldraw - Infinite canvas SDK
- Phosphor Icons - Icon library
- Zustand - State management