A powerful, client-side web application for composing images, animated GIFs, and videos with real-time preview and multi-format export capabilities.
- Drag & Drop Import: PNG, JPEG, GIF, and WebM files
- Real-time Thumbnails: Instant preview of all imported assets
- Format Detection: Automatic file type validation and handling
- Smart Organization: Asset browser with metadata display
- Multi-layer Composition: Unlimited layers with full z-order control
- Resizable Canvas: Multiple presets (1:1, 16:9, 9:16) and custom sizes
- Transform Controls: Move, resize, rotate, and adjust opacity
- Layer Management: Lock, hide, rename, and duplicate layers
- Real-time Preview: Smooth 60fps preview with configurable frame rates
- Configurable Loop Duration: Auto-detect from assets or custom timing
- Playback Controls: Play, pause, stop with speed adjustment (0.25Γ-2Γ)
- Frame-accurate Scrubbing: Precise timeline navigation
- Visual Timeline: Asset duration indicators and time markers
- Image Export: PNG and JPEG with quality control
- Animated GIF: Optimized with 256-color palette quantization
- WebM Video: Hardware-accelerated with alpha channel support
- Format Detection: Automatic browser capability detection
- Dark Interface: Easy on the eyes for long editing sessions
- Fire Accents: Warm orange/red color scheme throughout
- Responsive Layout: Works on desktop, tablet, and mobile devices
- Smooth Animations: Polished micro-interactions and transitions
- Node.js 20.x or higher
- Modern web browser with Canvas 2D support
# Clone the repository
git clone https://github.com/hankerspace/burnit.git
cd burnit
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:5173 to view the application.
# Build optimized bundle
npm run build
# Preview production build
npm run preview- Drag and drop files into the Assets panel
- Or click "browse files" to select files manually
- Supported formats: PNG, JPEG, GIF, WebM
- Click any asset to add it as a layer to the canvas
- Layers appear in the Layers panel in rendering order
- Use visibility π and lock π controls as needed
- Select layers to see transform handles on canvas
- Use the Inspector panel for precise numeric control
- Adjust position, scale, rotation, and opacity
- Set canvas size and frame rate in composition settings
- Use playback controls to preview your animation
- Adjust loop duration or let it auto-detect from assets
- Click Export to open the export dialog
- Choose format: PNG, JPEG, GIF, or WebM
- Adjust quality settings and click export
src/
βββ app/ # Main application component
βββ components/ # React components
β βββ Assets/ # Asset browser
β βββ Canvas/ # Canvas stage
β βββ Export/ # Export dialog
β βββ Inspector/ # Layer properties
β βββ LayerList/ # Layer management
β βββ Timeline/ # Playback controls
βββ lib/ # Core libraries
β βββ canvas/ # Canvas drawing utilities
β βββ gif/ # GIF encoding/decoding
β βββ media/ # Media recording
β βββ video/ # Video utilities
βββ state/ # Zustand state management
βββ types/ # TypeScript definitions
βββ utils/ # Utility functions
βββ test/ # Test files
# Development
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
# Code Quality
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint issues
npm run format # Format code with Prettier
npm run format:check # Check code formatting
# Testing
npm run test # Run tests in watch mode
npm run test:run # Run tests once
npm run test:ui # Run tests with UI
npm run test:e2e # Run E2E tests
npm run test:e2e:ui # Run E2E tests with UI- Frontend: React 19 + TypeScript (with strict type safety)
- Build Tool: Vite 7
- State Management: Zustand
- UI Components: Radix UI primitives
- Canvas: HTML5 Canvas 2D API
- Animation: RequestAnimationFrame
- GIF Processing: gifuct-js + gifenc
- Video: MediaRecorder API + HTMLVideoElement
- Testing: Vitest + Playwright
- Linting: ESLint + Prettier
- Code Quality: Strict TypeScript configuration with enhanced type safety
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
- Canvas 2D: All supported browsers
- WebM Import: Chrome, Firefox, Edge
- WebM Export: Chrome, Firefox, Edge (with MediaRecorder)
- Alpha Channel: Chrome, Firefox (VP8/VP9 with alpha)
- OffscreenCanvas: Chrome, Firefox (performance optimization)
- Web Workers: All supported browsers
The application gracefully degrades features based on browser capabilities.
The application uses Zustand for centralized state management with the following stores:
- Project State: Assets, layers, composition settings
- Timeline State: Playback, current time, speed
- Canvas State: Zoom, pan, selection
- UI State: Tool selection, grid settings
- Asset Loading: Files are converted to ImageBitmaps or VideoElements
- Layer Composition: Transforms are applied in Z-order
- Canvas Drawing: Real-time rendering with requestAnimationFrame
- Export Processing: Frames are captured and encoded
- Web Workers: GIF encoding off main thread
- OffscreenCanvas: Hardware-accelerated rendering when available
- ImageBitmap: Optimized image decoding
- Lazy Loading: Assets loaded on demand
- Memory Management: Automatic cleanup of resources
Located in src/test/, covering:
- State management logic
- Utility functions
- Canvas operations
- File handling
Located in tests/, covering:
- Application startup
- Asset import workflow
- Layer manipulation
- Export functionality
- Responsive behavior
# Unit tests
npm run test:run
# E2E tests (requires browser installation)
npx playwright install
npm run test:e2e- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
npm run test:run - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
- Use TypeScript for all new code
- Follow existing naming conventions
- Add tests for new functionality
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
- gifuct-js: GIF decoding library
- gifenc: GIF encoding library
- Radix UI: Accessible UI components
- Zustand: State management
- Vite: Build tool and development server
- WebM alpha channel support varies by browser
- Large GIF files may cause memory pressure
- Some mobile browsers have Canvas size limitations
Made with π₯ by Hankerspace
