A modern, powerful browser-based image editor built with FabricJS and TypeScript. This library provides a complete image editing solution with professional features for web applications.
- Montage Area - Dedicated workspace with clipping region for precise cropping
- Multi-layer Support - Layer management with ordering, visibility, and locking
- History System - Full undo/redo with state management
- Rich Text Editing - Text manager with typography controls, uppercase transforms, and history-aware updates
- Object Transformations - Zoom, rotate, flip, fit, and scale operations
- Professional Tools - Copy/paste, grouping, selection, and alignment
- Background Management - Color, gradient, and image backgrounds
- Image Import/Export - Support for PNG, JPG, SVG, and PDF formats
- Web Worker Integration - Heavy operations run in background threads
- Font Loader - FontManager handles Google Fonts + custom sources with automatic
@font-faceregistration - Configurable Toolbar - Dynamic toolbar with context-sensitive actions
- Clipboard Integration - Native copy/paste support with system clipboard
- TypeScript Support - Full type definitions included
- Modular Architecture - Clean separation of concerns with manager classes
- Event System - Rich event handling for integration
- Responsive Design - Adapts to different screen sizes and containers
- Testing Infrastructure - Jest test suite with 45%+ coverage
- Web Worker Support - Background processing for heavy operations
npm install @anu3ev/fabric-image-editorRequirements:
- Node.js ≥ 20.0.0
- NPM ≥ 9.0.0
- Modern browser with ES2016+ support
Create a container in your HTML and initialize the editor:
<div id="editor"></div>import initEditor from '@anu3ev/fabric-image-editor' document.addEventListener('DOMContentLoaded', async () => { const editor = await initEditor('editor', { montageAreaWidth: 512, montageAreaHeight: 512, editorContainerWidth: '100%', editorContainerHeight: '100vh' }) // The editor is now ready to use! console.log('Editor initialized:', editor) })// Import an image await editor.imageManager.importImage({ source: 'path/to/image.jpg', scale: 'image-contain' // 'image-contain', 'image-cover', 'scale-montage' }) // Export the canvas const result = await editor.imageManager.exportCanvasAsImageFile({ fileName: 'edited-image.png', contentType: 'image/png' // Supports: 'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf' }) // Handle the exported file (result.image is File, Blob, or Base64 string) const url = URL.createObjectURL(result.image) // Use the URL for download or display// Set a color background editor.backgroundManager.setColorBackground({ color: '#ff0000' }) // Set a gradient background editor.backgroundManager.setGradientBackground({ gradient: { // 'linear' or 'radial' type: 'linear', angle: 45, startColor: '#ff0000', endColor: '#0000ff' }, customData: { customProperty: 'value' }, withoutSave: false }) // Set an image background await editor.backgroundManager.setImageBackground({ imageSource: 'bg-image.jpg' }) // Remove background editor.backgroundManager.removeBackground()// Add a text layer with custom style const textbox = editor.textManager.addText({ text: 'Привет, Fabric!', fontFamily: 'Merriweather', fontSize: 64, bold: true, align: 'center', color: '#1f2933' }) // Update existing text editor.textManager.updateText({ target: textbox, style: { text: 'HELLO FABRIC', uppercase: true, strokeColor: '#2563eb', strokeWidth: 2 } }) // Background styling with padding and rounded corners const bgTextbox = editor.textManager.addText({ text: 'New text', backgroundColor: '#ffffff', backgroundOpacity: 0.85, paddingTop: 24, paddingRight: 32, paddingBottom: 24, paddingLeft: 32, radiusTopLeft: 8, radiusTopRight: 8, radiusBottomRight: 8, radiusBottomLeft: 8 }) editor.textManager.updateText({ target: bgTextbox, style: { paddingTop: 40, paddingBottom: 40, radiusTopLeft: 16, radiusTopRight: 16 } })By default the editor ships with a curated Google Fonts collection (Latin + Cyrillic coverage). If you want to use your own fonts, supply a fonts array – the provided list will replace the defaults.
import initEditor from '@anu3ev/fabric-image-editor' await initEditor('editor', { fonts: [ { family: 'Alegreya Sans', source: "url('https://fonts.gstatic.com/s/alegreyasans/v26/5aUz9_-1phKLFgshYDvh6Vwt7VptvQ.woff2') format('woff2')", descriptors: { style: 'normal', weight: '400', display: 'swap' } }, { family: 'My Custom Font', source: "url('https://example.com/fonts/my-font.woff2') format('woff2')", descriptors: { style: 'normal', weight: '400', display: 'swap', unicodeRange: 'U+0000-00FF' } } ] })ℹ️ Leave
fontsundefined to rely on the built-in defaults. Passing the property replaces that set with the fonts you specify.
The repository includes a comprehensive demo showcasing all features:
git clone https://github.com/Anu3ev/image-editor.git cd image-editor npm install npm run devVisit the demo at: https://anu3ev.github.io/image-editor/
The editor follows a modular architecture with specialized managers:
ImageManager- Image import/export, format handling, PDF generationCanvasManager- Canvas sizing, scaling, and viewport managementHistoryManager- Undo/redo functionality with state persistenceTextManager- Text object creation, styling, uppercase handling, and history integrationLayerManager- Object layering, z-index management, send to back/frontBackgroundManager- Background colors, gradients, and imagesTransformManager- Object transformations, fitting, and scaling
SelectionManager- Object selection and multi-selection handlingClipboardManager- Copy/paste with system clipboard integrationGroupingManager- Object grouping and ungrouping operationsDeletionManager- Object deletion with group handlingShapeManager- Shape creation (rectangles, circles, triangles)ObjectLockManager- Object locking and unlocking functionalityWorkerManager- Web Worker integration for heavy operationsFontManager- Font loading via FontFace API or fallback @font-face injectionModuleLoader- Dynamic module loading (jsPDF, etc.)ErrorManager- Error handling and user notificationsTemplateManager(src/editor/template-manager/index.ts) - Serializes and reapplies object/group templates with optional background preservation
ToolbarManager- Dynamic toolbar with configurable actionsCustomizedControls- Custom FabricJS controls and interactionsInteractionBlocker- UI blocking during operations
initEditor(containerId, options): Promise<ImageEditor>Parameters:
containerId(string) - HTML container element IDoptions(CanvasOptions) - Configuration object
Common Options:
{ // Canvas dimensions (internal resolution) montageAreaWidth: 512, montageAreaHeight: 512, // Container dimensions (display size) editorContainerWidth: '800px', editorContainerHeight: '600px', // Initial image initialImage: { source: 'path/to/image.jpg', scale: 'image-contain' }, // Content types for import acceptContentTypes: ['image/png', 'image/jpeg', 'image/svg+xml'], // Callback when ready _onReadyCallback: (editor) => console.log('Ready!') }// Import image from file or URL await editor.imageManager.importImage({ source: File | string, scale: 'image-contain' // or 'image-cover', 'scale-montage' }) // Export canvas as image await editor.imageManager.exportCanvasAsImageFile({ fileName: 'export.png', contentType: 'image/png' // 'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf' })// Scale montage area to fit image editor.canvasManager.scaleMontageAreaToImage() // Set canvas dimensions editor.canvasManager.setCanvasBackstoreWidth(800) editor.canvasManager.setCanvasBackstoreHeight(600) // Zoom operations editor.canvas.zoomToPoint(point, zoomLevel)// Fit object to montage area editor.transformManager.fitObject({ type: 'contain', fitAsOneObject: true }) // Reset object transformations editor.transformManager.resetObject() // Flip operations editor.transformManager.flipX() editor.transformManager.flipY()// Layer operations editor.layerManager.sendToBack(object) editor.layerManager.bringToFront(object) editor.layerManager.sendBackwards(object) editor.layerManager.bringForward(object)// Undo/Redo editor.historyManager.undo() editor.historyManager.redo() // Save state editor.historyManager.saveState() // Load from JSON editor.historyManager.loadStateFromFullState(jsonState)// Serialize current selection to JSON template const templateJson = editor.templateManager.serializeSelection({ includeBackground: false }) // Apply template to canvas await editor.templateManager.applyTemplate({ templateJson, clearCanvas: false })TemplateManager keeps layout fidelity by storing positions, styles, and (optionally) background data so you can rehydrate saved compositions.
# Development mode with demo app and watch npm run dev # Development build to dev-build folder npm run dev:build # Production build (library to dist/) npm run build # Build for GitHub Pages (demo to docs/) npm run build:docs# Run all tests npm test # Watch mode for development npm run test:watch # Coverage report npm run test:coverage # CI mode npm run test:cisrc/ ├── main.ts # Entry point, exports initEditor() ├── editor/ │ ├── index.ts # ImageEditor class │ ├── defaults.ts # Default configuration │ ├── constants.ts # Constants and limits │ ├── listeners.ts # Event handling │ ├── background-manager/ # Background functionality │ ├── canvas-manager/ # Canvas operations │ ├── clipboard-manager/ # Copy/paste operations │ ├── customized-controls/ # Custom FabricJS controls │ ├── deletion-manager/ # Object deletion │ ├── error-manager/ # Error handling │ ├── grouping-manager/ # Object grouping │ ├── history-manager/ # Undo/redo system │ ├── image-manager/ # Image import/export │ ├── interaction-blocker/ # UI blocking during operations │ ├── layer-manager/ # Layer management │ ├── module-loader/ # Dynamic module loading │ ├── object-lock-manager/ # Object locking │ ├── selection-manager/ # Selection handling │ ├── shape-manager/ # Shape creation │ ├── text-manager/ # Text objects and styling │ ├── font-manager/ # Font loading utilities │ ├── transform-manager/ # Object transformations │ ├── worker-manager/ # Web Worker management │ ├── ui/ # UI components (toolbar) │ └── types/ # TypeScript definitions ├── editor/default-fonts.ts # Built-in Google font presets ├── demo/ # Demo application specs/ # Test specifications docs/ # GitHub Pages build output dev-build/ # Development build output dist/ # Production library build vite.config.*.js # Vite configurations jest.config.ts # Jest test configuration The following features are planned for future releases:
- Drawing Mode - Freehand drawing tools and brushes
- Snap/Alignment - Snap to edges, centers, and guides
- Filters & Effects - Image filters and visual effects
- Extended Shape Library - Additional shapes beyond current rectangles, circles, and triangles
- Multi-language - Internationalization support
Contributions are welcome! Please feel free to submit a Pull Request.
git clone https://github.com/Anu3ev/image-editor.git cd image-editor npm install npm run devnpm test # Run all tests npm run test:watch # Development mode npm run test:coverage # Coverage report- Chrome ≥ 88
- Firefox ≥ 85
- Safari ≥ 14
- Edge ≥ 88
All modern browsers with ES2016+ and Web Workers support.
MIT License - see LICENSE file for details.
- Built with FabricJS - Powerful HTML5 canvas library
- Vite - Lightning fast build tool
- TypeScript - Type safety and developer experience
- Jest - Comprehensive testing framework
Repository: github.com/Anu3ev/image-editor
NPM Package: @anu3ev/fabric-image-editor
Live Demo: anu3ev.github.io/image-editor