Skip to content

Repository files navigation

Fuderu Logo

Stable 1.3.2 canvas drawing engine for the web.

interpolation | adaptive spacing | pressure | image brushes | modules


npm version Downloads License Docs

Features

  • 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.

Release Focus

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.

Latest Release

1.3.2

  • Document Persistence Layer Lock Serialization: exportDocument() and importDocument() now preserve alphaLock and locked layer 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.

1.3.1

  • Off-Document Command Safety: Prevents out-of-bounds vector shapes (drawRectangle, drawEllipse, drawLine, drawText) from throwing getImageData exceptions or pushing empty history patches.
  • Multi-Touch Gesture Isolation: Pointer events track unique pointerId per 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.

1.3.0

  • First-Class Document Persistence API: Native exportDocument() and importDocument() with typed, versioned document data (width, height, layers, activeLayerId, and serialized bitmaps), plus exportPNG() for flattened composite output.
  • Advanced Layer Controls: Added alphaLock (restricts editing to existing non-transparent pixels) and locked (protects layers from edits/deletion), plus direct Canvas methods (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) for change, stroke:start, stroke:end, layer:change, and history:change, alongside getSnapshot().
  • Public History Navigation & Patching: Jump to any point in history with canvas.history.goTo(index) and push custom raster tool undo patches via canvas.history.pushPatch().

For details on earlier releases (v1.0.0 – v1.2.2), please refer to the CHANGELOG.md.

Installation

npm install fuderu

Quick Start

import { 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();

Layer System

Fuderu includes a full layer stack with Photoshop-like capabilities.

Layer Management

// 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);

Blend Modes

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

Flow And Opacity

  • 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.

Image Brushes

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.

Modules

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,
  }),
);

Built-in modules:

  • DynamicShapeModule – Size, angle, and roundness jitter
  • DynamicTransparencyModule – Opacity and flow jitter
  • SpreadModule – Position scatter
  • PatternModule – Pattern-based stamping

Status

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.

License

MIT

About

Lightweight, extensible canvas drawing engine for the web.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages