@anth0nycodes/fabric-history
v1.1.0
Published
A library built on top of fabric.js that allows for easy access to canvas history.
Downloads
1,197
Maintainers
Readme
fabric-history
A library built on top of fabric.js that provides undo/redo history management for canvas operations.
Features
- Undo/Redo functionality for fabric.js canvases
- Automatic history tracking for path creation, erasing events, object additions, removals, and modifications
- Multi-selection batching: operations on multiple selected objects are recorded as a single history entry
- Custom events for history state changes
- Fully type-safe
- Support for fabric.js v6 and v7
Installation
npm install @anth0nycodes/fabric-historyor with pnpm:
pnpm add @anth0nycodes/fabric-historyor with yarn:
yarn add @anth0nycodes/fabric-historyUsage
import { CanvasWithHistory } from "@anth0nycodes/fabric-history";
import { Rect } from "fabric";
// Create a canvas with history support (same constructor as fabric.Canvas)
const canvas = new CanvasWithHistory("my-canvas", {
width: 800,
height: 600,
});
// Add objects - history is tracked automatically
const rect = new Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: "red",
});
canvas.add(rect);
// Undo the last action
await canvas.undo();
// Redo the undone action
await canvas.redo();Using with @erase2d/fabric
To enable history tracking for erasing operations, use the setEraserBrush method with an EraserBrush from @erase2d/fabric. This ensures that erasing actions trigger the erasing:end event required for history tracking.
import { CanvasWithHistory } from "@anth0nycodes/fabric-history";
import { EraserBrush } from "@erase2d/fabric";
const canvas = new CanvasWithHistory("my-canvas", {
width: 800,
height: 600,
});
// Create and set the eraser brush
const eraser = new EraserBrush(canvas);
eraser.width = 20;
canvas.setEraserBrush(eraser);
// Enable drawing mode to use the eraser
canvas.isDrawingMode = true;API
CanvasWithHistory
Extends fabric.js Canvas class with history management capabilities.
Methods
| Method | Returns | Description |
| ------------------------ | --------------- | ---------------------------------------------------------------------------------------------------- |
| undo() | Promise<void> | Undo the most recent action |
| redo() | Promise<void> | Redo the most recently undone action |
| canUndo() | boolean | Check if an undo action is available |
| canRedo() | boolean | Check if a redo action is available |
| setEraserBrush(eraser) | void | Set an EraserBrush from @erase2d/fabric to enable history tracking for erasing operations |
| clearHistory() | void | Clear the undo and redo history stacks |
| clearCanvas() | void | Clear the canvas and save the cleared state to history (use this instead of the inherited clear()) |
| dispose() | void | Clean up event listeners and dispose the canvas |
Tracked Events
History is automatically saved when these fabric.js events occur:
path:created- When a path is created (e.g., freehand drawing)erasing:end- When an erasing operation completesobject:added- When an object is added to the canvasobject:removed- When an object is removed from the canvasobject:modified- When an object is modified (moved, scaled, rotated, etc.)
Custom Events
CanvasWithHistory fires custom events that you can listen to for history state changes:
| Event | Payload | Description |
| ----------------- | ------------------------------------ | --------------------------------- |
| history:append | { json: string, initial: boolean } | Fired when a state is saved |
| history:undo | { lastUndoAction: string } | Fired when an undo is performed |
| history:redo | { lastRedoAction: string } | Fired when a redo is performed |
| history:cleared | {} | Fired when history stacks cleared |
Example:
canvas.on("history:append", ({ json, initial }) => {
console.log("State saved:", initial ? "initial" : "action");
});
canvas.on("history:undo", ({ lastUndoAction }) => {
console.log("Undo performed");
});Requirements
- fabric.js 6.x or 7.x
Development
# Install dependencies
pnpm install
# Run development server
pnpm dev
# Build the project
pnpm build
# Type check
pnpm check
# Run all tests
pnpm test
# Run integration tests only
pnpm test:it
# Run E2E tests only (uses Playwright)
pnpm test:e2e
# Run tests with coverage
pnpm coverageContributing
Contributions are welcome! Please read our CONTRIBUTING.md for details on how to submit pull requests.
License
MIT
Author
Anthony Hoang
