image-editor-canva
Version:
A Canva-like image editor plugin for React
437 lines (381 loc) • 9.11 kB
Markdown
# Image Editor Canvas
A powerful and customizable image editor built with React and Fabric.js.
## Features
- 🎨 Rich set of editing tools
- 📝 Text editing with multiple fonts and styles
- 🖼️ Image manipulation and filters
- 🎯 Shape drawing and manipulation
- 🎨 Color management
- 📏 Size and position controls
- 🔄 Undo/Redo functionality
- 💾 Multiple export formats (PNG, JPG, SVG, JSON)
- ⌨️ Keyboard shortcuts
- 🎯 Selection tools
- 🖌️ Drawing tools
- 🎨 Background customization
- 📦 Template support
## Installation
```bash
npm install image-editor-canvas
# or
yarn add image-editor-canvas
```
## Basic Usage
```tsx
import { Editor } from 'image-editor-canvas';
function App() {
return (
<Editor
initialData={{
json: "",
name: "New Project",
id: '123',
userId: "anonymous",
height: 720,
width: 1280,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
onClose={() => {
// Handle editor close
console.log('Editor closed');
}}
/>
);
}
```
## Advanced Usage Examples
### 1. Using Editor Hooks
```tsx
import { useEditor, Editor } from 'image-editor-canvas';
function CustomEditor() {
const { editor } = useEditor({
defaultState: "",
defaultWidth: 1280,
defaultHeight: 720,
saveCallback: (values) => {
console.log('Editor saved:', values);
},
closeCallback: () => {
console.log('Editor closed');
}
});
return (
<Editor
initialData={{
json: "",
name: "Custom Project",
id: '456',
userId: "user123",
height: 720,
width: 1280,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
/>
);
}
```
### 2. Working with Templates
```tsx
import { Editor } from 'image-editor-canvas';
const templates = [
{
id: 'template1',
name: 'Social Media Post',
width: 1080,
height: 1080,
thumbnailUrl: '/templates/social-post.png',
json: {
version: "5.3.0",
objects: [
// Template objects
]
}
}
];
function App() {
return (
<Editor
initialData={{
json: "",
name: "New Project",
id: '123',
userId: "anonymous",
height: 1080,
width: 1080,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
templates={templates}
templateImagePath="/templates"
/>
);
}
```
### 3. Custom Toolbar Implementation
```tsx
import { Editor, useEditor, Toolbar } from 'image-editor-canvas';
import { useState } from 'react';
function CustomToolbarEditor() {
const [activeTool, setActiveTool] = useState('select');
const { editor } = useEditor({
defaultState: "",
defaultWidth: 1280,
defaultHeight: 720
});
return (
<div className="custom-editor">
<Toolbar
editor={editor}
activeTool={activeTool}
onChangeActiveTool={setActiveTool}
/>
<Editor
initialData={{
json: "",
name: "Custom Toolbar Project",
id: '789',
userId: "user456",
height: 720,
width: 1280,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
/>
</div>
);
}
```
### 4. Exporting and Saving
```tsx
import { Editor, useEditor } from 'image-editor-canvas';
import { useCallback } from 'react';
function ExportExample() {
const { editor } = useEditor({
defaultState: "",
defaultWidth: 1280,
defaultHeight: 720
});
const handleExport = useCallback((format: 'png' | 'jpg' | 'svg' | 'json') => {
if (!editor) return;
switch (format) {
case 'png':
editor.savePng();
break;
case 'jpg':
editor.saveJpg();
break;
case 'svg':
editor.saveSvg();
break;
case 'json':
editor.saveJson();
break;
}
}, [editor]);
return (
<div>
<div className="export-buttons">
<button onClick={() => handleExport('png')}>Export PNG</button>
<button onClick={() => handleExport('jpg')}>Export JPG</button>
<button onClick={() => handleExport('svg')}>Export SVG</button>
<button onClick={() => handleExport('json')}>Export JSON</button>
</div>
<Editor
initialData={{
json: "",
name: "Export Example",
id: 'export123',
userId: "user789",
height: 720,
width: 1280,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
/>
</div>
);
}
```
### 5. Working with Text
```tsx
import { Editor, useEditor } from 'image-editor-canvas';
import { useCallback } from 'react';
function TextEditorExample() {
const { editor } = useEditor({
defaultState: "",
defaultWidth: 1280,
defaultHeight: 720
});
const addText = useCallback(() => {
if (!editor) return;
editor.addText('Hello World', {
fontSize: 48,
fontFamily: 'Arial',
fill: '#000000'
});
}, [editor]);
const changeFont = useCallback((fontFamily: string) => {
if (!editor) return;
editor.changeFontFamily(fontFamily);
}, [editor]);
return (
<div>
<div className="text-controls">
<button onClick={addText}>Add Text</button>
<select onChange={(e) => changeFont(e.target.value)}>
<option value="Arial">Arial</option>
<option value="Times New Roman">Times New Roman</option>
<option value="Helvetica">Helvetica</option>
</select>
</div>
<Editor
initialData={{
json: "",
name: "Text Example",
id: 'text123',
userId: "user101",
height: 720,
width: 1280,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
/>
</div>
);
}
```
### 6. Working with Shapes
```tsx
import { Editor, useEditor } from 'image-editor-canvas';
import { useCallback } from 'react';
function ShapeEditorExample() {
const { editor } = useEditor({
defaultState: "",
defaultWidth: 1280,
defaultHeight: 720
});
const addShape = useCallback((type: 'rectangle' | 'circle' | 'triangle') => {
if (!editor) return;
switch (type) {
case 'rectangle':
editor.addRectangle();
break;
case 'circle':
editor.addCircle();
break;
case 'triangle':
editor.addTriangle();
break;
}
}, [editor]);
return (
<div>
<div className="shape-controls">
<button onClick={() => addShape('rectangle')}>Add Rectangle</button>
<button onClick={() => addShape('circle')}>Add Circle</button>
<button onClick={() => addShape('triangle')}>Add Triangle</button>
</div>
<Editor
initialData={{
json: "",
name: "Shape Example",
id: 'shape123',
userId: "user202",
height: 720,
width: 1280,
thumbnailUrl: null,
isTemplate: null,
isPro: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}}
/>
</div>
);
}
```
## Props
### Editor Component Props
| Prop | Type | Description |
|------|------|-------------|
| `initialData` | `Object` | Initial editor data |
| `templates` | `Array` | Optional array of templates |
| `templateImagePath` | `string` | Path to template images |
| `onClose` | `Function` | Callback when editor is closed |
### Editor Data Structure
```typescript
interface EditorData {
json: string;
name: string;
id: string;
userId: string;
height: number;
width: number;
thumbnailUrl: string | null;
isTemplate: boolean | null;
isPro: boolean | null;
createdAt: string;
updatedAt: string;
}
```
## Available Tools
- Select
- Shapes
- Text
- Images
- Elements
- Draw
- Fill
- Stroke Color
- Stroke Width
- Font
- Opacity
- Filter
- Settings
- AI
- Remove Background
- Background
- Templates
## Export Formats
- PNG
- JPG
- SVG
- JSON
## Keyboard Shortcuts
- `Ctrl + Z` / `Cmd + Z`: Undo
- `Ctrl + Y` / `Cmd + Y`: Redo
- `Ctrl + C` / `Cmd + C`: Copy
- `Ctrl + V` / `Cmd + V`: Paste
- `Delete`: Delete selected object
- `Ctrl + S` / `Cmd + S`: Save
## Development
```bash
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
```
## License
MIT