Events
Handle editor lifecycle events, canvas interactions, and object changes.
Configuration Callbacks
Configuration callbacks are passed directly to Imigi.init() and fire during key lifecycle moments of the editor. These are the primary way to react to high-level editor events.
onLoad
onLoad: (editor: Imigi) => void
Called when the editor is fully initialized and ready. The editor instance is passed as a parameter. This is the best place to store a reference to the editor and set up any custom logic.
Imigi.init({
selector: '#editor',
image: 'photo.jpg',
onLoad: (editor) => {
console.log('Editor is ready!');
window.imigi = editor; // store reference
},
});
Always use onLoad to store the editor reference. Trying to use the editor before it fires may result in undefined behavior.
onSave
onSave: (data: string, filename: string, format: ExportFormat) => void
Called when the user clicks save. The data parameter is a base64-encoded string for image formats or a JSON string when saving state. The filename is the suggested file name. The format is one of 'png', 'jpeg', 'json', or 'svg'.
Imigi.init({
selector: '#editor',
image: 'photo.jpg',
onSave: (data, filename, format) => {
if (format === 'json') {
// Save editor state
localStorage.setItem('editor-state', data);
} else {
// Upload image to server
fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({ data, filename, format }),
headers: { 'Content-Type': 'application/json' },
});
}
},
});
Base64 image data can be very large. For production use, consider streaming the upload or converting to a Blob before sending to the server.
onClose
onClose: () => void
Called when the editor is closed (in overlay mode) or when the close button is clicked. Use this to clean up resources or restore page state.
onOpen
onOpen: () => void
Called when the editor opens in overlay mode. Useful for disabling background scrolling, tracking analytics, or adjusting layout.
onFileOpen
onFileOpen: (file: UploadedFile) => void
Called when a file is uploaded or opened in the editor. The file object contains the file's name, size, and type.
Imigi.init({
selector: '#editor',
onFileOpen: (file) => {
console.log('Opened:', file.name);
console.log('Size:', (file.size / 1024).toFixed(1) + ' KB');
console.log('Type:', file.type);
},
});
onMainImageLoaded
onMainImageLoaded: (image: FabricImage) => void
Called when the main background image finishes loading onto the canvas. The image parameter is the Fabric.js image object. Use this to perform operations that depend on image dimensions or to apply initial transformations.
Imigi.init({
selector: '#editor',
image: 'photo.jpg',
onMainImageLoaded: (image) => {
console.log('Image dimensions:', image.width, 'x', image.height);
},
});
Canvas Events (via imigi.on())
Canvas events provide fine-grained control over interactions happening on the Fabric.js canvas. Subscribe to them using imigi.on() after the editor has loaded.
Always subscribe to canvas events inside the onLoad callback to ensure the editor instance is ready.
Mouse Events
| Event | Description |
|---|---|
mouse:down |
Mouse button pressed on canvas |
mouse:move |
Mouse moved over canvas |
mouse:up |
Mouse button released |
mouse:wheel |
Mouse wheel scrolled |
mouse:over |
Mouse enters canvas |
mouse:out |
Mouse leaves canvas |
mouse:dblclick |
Double click on canvas |
Object Events
| Event | Description |
|---|---|
object:added |
Object added to canvas |
object:removed |
Object removed from canvas |
object:modified |
Object finished being modified (moved, scaled, rotated) |
object:moving |
Object is being moved (fires continuously) |
object:scaling |
Object is being scaled |
object:rotating |
Object is being rotated |
object:skewing |
Object is being skewed |
Events like object:moving, object:scaling, and object:rotating fire continuously during interaction. Avoid heavy computations in their handlers -- use debouncing or throttling when needed.
Selection Events
| Event | Description |
|---|---|
selection:created |
New selection made |
selection:updated |
Selection changed |
selection:cleared |
Selection cleared / deselected |
Text Events
| Event | Description |
|---|---|
text:editing:entered |
Text editing mode entered |
text:editing:exited |
Text editing mode exited |
text:changed |
Text content changed |
Render Events
| Event | Description |
|---|---|
before:render |
Before canvas renders |
after:render |
After canvas renders |
canvas:cleared |
Canvas has been cleared |
Event Handler Pattern
Use imigi.on() to subscribe to any canvas event. The callback receives an event object with details about the interaction.
// Subscribe to events
imigi.on('object:modified', (e) => {
console.log('Object modified:', e.target);
});
The event object (e) typically includes a target property referencing the Fabric.js object involved, along with event-specific data such as pointer coordinates.
Practical Examples
Below are real-world patterns that demonstrate how to combine configuration callbacks and canvas events for common use cases.
Auto-save on Changes
Automatically save the editor state to localStorage after a period of inactivity following any modification.
let saveTimer;
imigi.on('object:modified', () => {
clearTimeout(saveTimer);
saveTimer = setTimeout(() => {
const state = imigi.getState();
localStorage.setItem('editor-autosave', state);
console.log('Auto-saved!');
}, 2000);
});
Debouncing with a 2-second delay prevents excessive writes to storage while still capturing all changes reliably.
Track Object Count
Keep a running count of objects on the canvas whenever objects are added or removed.
imigi.on('object:added', () => {
console.log('Objects:', imigi.tools.objects.getAll().length);
});
imigi.on('object:removed', () => {
console.log('Objects:', imigi.tools.objects.getAll().length);
});
Prevent Close with Unsaved Changes
Prompt the user before closing the editor if there are unsaved changes.
Imigi.init({
selector: '#editor',
image: 'photo.jpg',
onClose: () => {
if (imigi.isDirty()) {
const confirm = window.confirm('You have unsaved changes. Close anyway?');
if (!confirm) return;
}
// proceed with close
},
});
The isDirty() method returns true if any modifications have been made since the last save or since the editor was initialized.
Log All Object Modifications
Capture detailed information about every object modification for debugging or analytics.
imigi.on('object:modified', (e) => {
const obj = e.target;
console.log({
type: obj.name,
position: { left: obj.left, top: obj.top },
size: { width: obj.width * obj.scaleX, height: obj.height * obj.scaleY },
rotation: obj.angle,
});
});
Disable Scroll When Editor is Open (Overlay)
Prevent page scrolling behind the editor when it is opened in overlay mode, and restore it when closed.
Imigi.init({
selector: '#editor',
ui: { mode: 'overlay' },
onOpen: () => {
document.body.style.overflow = 'hidden';
},
onClose: () => {
document.body.style.overflow = '';
},
});
This pattern is especially important on mobile devices where background scrolling behind an overlay can cause a confusing user experience.