Stable 1.3.2 canvas drawing engine for the web.
interpolation | adaptive spacing | pressure | image brushes | modules
- Document Persistence API – Export and import complete canvas state as versioned JSON with layer metadata and serialized bitmaps (
exportDocument,importDocument,exportPNG). - Advanced Layer Controls – Full layer stack with visibility, opacity, 16 blend modes, Alpha Lock (clip strokes to opaque pixels), and Layer Lock (protect layers from modifications).
- Native Commands & Raster Operations – Fast scanline flood fill (
floodFill), vector shape primitives (drawRectangle,drawEllipse,drawLine), text rendering (drawText), and color sampling (getColorAt). - Observable State & Event System – Reactive canvas event subscriptions (
change,stroke:start,stroke:end,layer:change,history:change) and state snapshotting (getSnapshot). - Public History Navigation API – Direct history timeline jumping (
goTo), step summaries, and sparse bounding-box patch registration (pushPatch). - Canvas API & Direct Layer Methods – Direct layer stack helpers (
getLayers,getLayerById,reorderLayers) and pointer gesture handling. - Standalone Brush Engine – Smooth Bezier interpolation, adaptive spacing, real pressure sensitivity, custom image brushes, and extensible dynamic modules.
- TypeScript-First – Full type safety with a framework-agnostic design.
For Fuderu 1.3.2, the engine introduces serialized layer lock persistence across document JSON cycles, high-performance canvas context reuse for color parsing, and complete teardown cleanup on canvas destruction.
- Document Persistence Layer Lock Serialization:
exportDocument()andimportDocument()now preservealphaLockandlockedlayer options across document saves. - Optimized Color Parsing:
parseCssColor()reuses a shared 1x1 canvas context, eliminating DOM canvas allocation overhead on color evaluation. - Canvas Lifecycle Teardown:
destroy()clears event listeners and resets active pointer state cleanly.
- Off-Document Command Safety: Prevents out-of-bounds vector shapes (
drawRectangle,drawEllipse,drawLine,drawText) from throwinggetImageDataexceptions or pushing empty history patches. - Multi-Touch Gesture Isolation: Pointer events track unique
pointerIdper active stroke to avoid gesture conflicts from multi-touch input. - Tighter Rotated Ellipse Bounds: Exact rotated ellipse boundary calculations minimize history patch memory consumption during
drawEllipse.
- First-Class Document Persistence API: Native
exportDocument()andimportDocument()with typed, versioned document data (width,height,layers,activeLayerId, and serialized bitmaps), plusexportPNG()for flattened composite output. - Advanced Layer Controls: Added
alphaLock(restricts editing to existing non-transparent pixels) andlocked(protects layers from edits/deletion), plus directCanvasmethods (getLayers(),getLayerById(),reorderLayers()). - Native Raster Commands: Built-in scanline
floodFill(), vector shape primitives (drawRectangle,drawEllipse,drawLine), raster text (drawText), and pixel color sampling (getColorAt). - Observable State & Event Model: Typed event subscriptions (
on/off) forchange,stroke:start,stroke:end,layer:change, andhistory:change, alongsidegetSnapshot(). - Public History Navigation & Patching: Jump to any point in history with
canvas.history.goTo(index)and push custom raster tool undo patches viacanvas.history.pushPatch().
For details on earlier releases (v1.0.0 – v1.2.2), please refer to the CHANGELOG.md.
npm install fuderuimport { Canvas } from "fuderu";
const painter = new Canvas({
canvas: "#canvas",
document: {
width: 1536,
height: 1536,
},
pressureSimulation: true,
brush: {
color: "#000000",
size: 20,
spacing: 0.5,
},
});
// Layer management
const layer = painter.createLayer("Sketch");
painter.setActiveLayer(layer.id);
painter.loadConfig({
color: "#ff6b6b",
size: 32,
eraser: false,
});
painter.undo();
painter.redo();
painter.clear();Fuderu includes a full layer stack with Photoshop-like capabilities.
// Create a layer
const sketch = painter.createLayer("Sketch");
// Get all layers
const layers = painter.getLayers();
// Get active layer
const active = painter.getActiveLayer();
// Set active layer
painter.setActiveLayer(sketch.id);
// Update layer properties
painter.updateLayer(sketch.id, {
name: "Final Sketch",
visible: true,
opacity: 0.8,
blendMode: "multiply",
});
// Duplicate a layer
const copy = painter.duplicateLayer(sketch.id);
// Move layer (stack order)
painter.moveLayer(sketch.id, 0); // Move to bottom
// Delete a layer
painter.deleteLayer(sketch.id);Currently available blend modes:
| Mode | Description |
|---|---|
| source-over | Normal |
| multiply | Darkens with underlying colors |
| screen | Lightens with underlying colors |
| overlay | Combines multiply and screen |
| darken | Keeps darker colors |
| lighten | Keeps lighter colors |
| color-dodge | Brightens underlying colors |
| color-burn | Darkens underlying colors |
| hard-light | Strong overlay effect |
| soft-light | Soft overlay effect |
| difference | Subtracts colors |
| exclusion | Similar to difference but softer |
| hue | Uses hue of top layer |
| saturation | Uses saturation of top layer |
| color | Uses hue and saturation of top layer |
| luminosity | Uses luminosity of top layer |
- Opacity – Stroke-level ceiling (0-1). Applied once per stroke.
- Flow – Per-stamp alpha buildup. Lower flow = slower paint buildup.
- Spacing-Aware Flow – Automatically compensates for dense stamp spacing.
await painter.loadImage("/brushes/star.png");
painter.loadConfig({
rotation: {
mode: "flow",
smoothing: 0.15,
},
});Transparent images can be used as brush stamps with recoloring and rotation.
import { Brush, DynamicShapeModule, SpreadModule } from "fuderu";
const brush = new Brush(canvas, {
color: "#111111",
size: 24,
});
brush.useModule(
new DynamicShapeModule({
sizeJitter: 0.4,
sizeJitterTrigger: "pressure",
}),
);
brush.useModule(
new SpreadModule({
spreadRange: 0.3,
count: 3,
}),
);- DynamicShapeModule – Size, angle, and roundness jitter
- DynamicTransparencyModule – Opacity and flow jitter
- SpreadModule – Position scatter
- PatternModule – Pattern-based stamping
Fuderu 1.3.2 is the current stable release, providing a complete canvas engine with layer controls (including Alpha Lock and Layer Lock), native raster commands, multi-pointer gesture safety, state events, document persistence with lock state serialization, pressure sensitivity, and extensible brush modules.
The library is fully verified with robust unit testing via Vitest, browser-style canvas rendering tests, and various local playground environments across multiple web frameworks.
For full detailed guides and API documentations, check out the live documentation portal or look under the /docs folder.
