https://github.com/anth0nycodes/fabric-history
A library built on top of fabric.js that allows for easy access to canvas history.
https://github.com/anth0nycodes/fabric-history
Last synced: 3 months ago
JSON representation
A library built on top of fabric.js that allows for easy access to canvas history.
- Host: GitHub
- URL: https://github.com/anth0nycodes/fabric-history
- Owner: anth0nycodes
- License: mit
- Created: 2026-02-03T20:42:08.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-11T20:14:52.000Z (4 months ago)
- Last Synced: 2026-02-12T04:26:52.859Z (4 months ago)
- Language: TypeScript
- Size: 41 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
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
```bash
npm install @anth0nycodes/fabric-history
```
or with pnpm:
```bash
pnpm add @anth0nycodes/fabric-history
```
or with yarn:
```bash
yarn add @anth0nycodes/fabric-history
```
## Usage
```typescript
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`](https://github.com/erase2d/fabric). This ensures that erasing actions trigger the `erasing:end` event required for history tracking.
```typescript
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` | Undo the most recent action |
| `redo()` | `Promise` | 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 completes
- `object:added` - When an object is added to the canvas
- `object:removed` - When an object is removed from the canvas
- `object: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:**
```typescript
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
```bash
# 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 coverage
```
## Contributing
Contributions are welcome! Please read our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to submit pull requests.
## License
MIT
## Author
Anthony Hoang