This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
PopArt is an AI-powered infinite canvas web application for image generation and editing. It uses tldraw as the canvas SDK with AI image generation (Gemini & Seedream models).
npm run dev # Start dev server on port 3000
npm run build # TypeScript check + Vite build
npm run lint # ESLint
npm run preview # Preview production build- Canvas: tldraw v2 - handles infinite canvas, pan/zoom, shape management, persistence
- AI Image Generation: Gemini & Seedream models
- State: Zustand for AI generation state; tldraw manages canvas state with localStorage persistence
- Styling: TailwindCSS
-
tldraw Integration: The app uses tldraw's
TLComponentssystem to inject custom UI (InFrontOfTheCanvas) for the floating toolbar and prompt panel. TheuseEditor()hook provides access to the tldraw editor instance. -
Image Assets: All images are stored as base64 data URLs in tldraw's asset store (
src/utils/imageAssets.ts). ThecreateImageAssetStore()function handles image uploads and resolution. -
AI Services: Located in
src/services/ai/:imageGeneration.ts- Gemini & Seedream models
-
UI Components: Main floating UI components:
BottomPromptPanel- AI generation input with model selection and reference image supportFloatingToolbar- Image actions (copy, download) positioned above selected imageSettingsModal- API Key configuration modal
-
API Key Management: Users must configure their own API Key via the settings modal (gear icon at bottom right). Keys are stored in localStorage (
src/utils/apiKeyStorage.ts).
- User enters prompt in
BottomPromptPanel useAIStore.generateImage()callsimageGeneration.ts- Base64 response converted to data URL
addImageToCanvas()creates tldraw asset + shape
Users configure their API Key through the in-app settings modal (no environment variables needed). The key is stored in localStorage.
const editor = useEditor()
// Create image asset
editor.createAssets([{ id: assetId, type: 'image', ... }])
// Create image shape
editor.createShape({ type: 'image', x, y, props: { assetId, w, h } })
// Get selected shapes
editor.getSelectedShapes()
// Convert coordinates
editor.pageToScreen({ x, y })
editor.getViewportScreenCenter()Use addImageToCanvas() from src/utils/imageAssets.ts - handles asset creation, dimension scaling, and positioning.