Skip to main content

Canvas Wrapper

Canvas is the ergonomic entry point. It accepts either a canvas element or a query selector, creates a Brush, configures the canvas for the current device pixel ratio or an explicit document size, and binds pointer events.

Canvas wrapper live demo

The Canvas wrapper wires pointer events, pressure simulation, and device scaling automatically.

Loading demo…
import { Canvas } from "fuderu";

const painter = new Canvas({
canvas: document.querySelector("canvas")!,
document: {
width: 1024,
height: 768,
},
pressureSimulation: false,
brush: {
color: "#222222",
size: 18,
roundness: 0.8,
},
});

Document Size

The visible canvas size comes from CSS. The drawing buffer comes from document.width and document.height, or from the element's CSS size multiplied by window.devicePixelRatio when document is omitted.

const painter = new Canvas({
canvas: "#paint",
document: {
width: 1536,
height: 1536,
},
});

Call resize() after changing the element's visible size:

painter.resize();

Call setDocumentSize() to change the logical artwork size. This clears the canvas and resets undo history.

painter.setDocumentSize(2048, 2048);

Pressure

Real pen pressure is used when the pointer is a pen and event.pressure is available. Mouse and touch input can use simulated pressure:

const painter = new Canvas({
canvas: "#paint",
pressureSimulation: false,
});

Set pressureSimulation to true to enable simulated pressure based on movement speed for mouse and touch input.

lastPressure stores the most recent pressure sent to the brush, which is handy for UI meters without advancing the pressure simulator again.

Layer System

Fuderu includes a professional layer system that allows you to create, manage, and composite multiple layers similar to professional digital art software.

Layer Management

The Canvas instance includes a layers property that provides access to the layer management API:

// Create a new layer (this automatically sets it as active)
const layer = painter.createLayer({
name: "Line Art",
opacity: 0.8,
blendMode: "multiply",
});

// Get the active layer (which is now the new layer)
const activeLayer = painter.getActiveLayer();

// Set a layer as active manually using its ID
painter.setActiveLayer(layer.id);

// Delete a layer by ID
painter.deleteLayer("some-layer-id");

// Duplicate a layer
const duplicatedLayer = painter.duplicateLayer(layer.id);

// Get all layers
const allLayers = painter.getLayers();

// Update layer properties by ID
painter.updateLayer(layer.id, {
opacity: 0.5,
blendMode: "screen",
visible: true,
});

Blend Modes

Layers support standard Canvas 2D blend modes for advanced compositing effects:

  • source-over (default) - Normal layer stacking
  • multiply - Darkens the base layer
  • screen - Lightens the base layer
  • overlay - Combines multiply and screen
  • darken - Keeps the darker of the two layers
  • lighten - Keeps the lighter of the two layers
  • color-dodge - Brightens the base layer
  • color-burn - Darkens the base layer
  • hard-light - Intense overlay effect
  • soft-light - Soft overlay effect
  • difference - Subtracts the darker color from the lighter
  • exclusion - Similar to difference but lower contrast
  • hue - Applies the hue of the blend layer
  • saturation - Applies the saturation of the blend layer
  • color - Applies both hue and saturation
  • luminosity - Applies the luminosity of the blend layer

Example using blend modes for a multiply blending effect:

// Create a base color layer
const baseLayer = painter.createLayer({
name: "Base Color",
blendMode: "source-over",
});

// Draw your base colors on this layer
// ...

// Create a shading layer with multiply blend mode
const shadeLayer = painter.createLayer({
name: "Shading",
blendMode: "multiply",
});

// Draw shadows and shading on this layer
// The multiply blend mode will darken the colors below

Layer Properties

Each layer has the following properties:

  • id - Unique identifier for the layer
  • name - Human-readable name for the layer
  • visible - Whether the layer is visible (default: true)
  • opacity - Opacity of the layer (0-1, default: 1)
  • blendMode - How the layer composites with layers below it

Direct Layer Manager Access

For advanced layer operations, you can access the underlying `LayerManager` instance via the `layers` property on the Canvas:

// Move a layer to a specific index (0-based)
painter.layers.moveLayer(layerId, targetIndex);

// Resize all layers (called automatically when canvas size changes)
painter.layers.resize(width, height);

// Clear all layers
painter.layers.clear();

// Get readonly array of all layers
const allLayers = painter.layers.getAll();

Access The Brush

The wrapper exposes the underlying brush:

painter.brush.blendMode = "multiply";
painter.brush.filter = "blur(0.2px)";
painter.brush.maxUndoRedoStackSize = 20;

Use this when the high-level wrapper is still useful, but you need a lower-level brush feature.