Skip to main content

Module API

Modules are plain objects or classes that implement one or more hook methods.

Module hook behavior

Toggle dynamic shape, transparency, spread, and pattern compositing to see how module hooks alter points, per-stamp config, and stroke mix-in.

Loading demo…
interface Module {
onChangeConfig?(config: BrushBasicConfig, pressure: number): void;
onChangePoint?(
point: PurePoint,
config: BrushBasicConfig,
): PurePoint | PurePoint[];
onMixinCanvas?(
strokeCanvas: HTMLCanvasElement,
strokeContext: CanvasRenderingContext2D,
): [HTMLCanvasElement, CanvasRenderingContext2D];
onEndStroke?(): void;
}

Built-in modules also expose config and bindConfig(config), so you can either mutate settings directly or replace the config reference with app state.

Hooks

onChangePoint

Runs before a point becomes a rendered stamp. Return one point to transform the input, or multiple points to create extra stamps.

onChangeConfig

Runs for each stamp with a copy of the active brush config. Mutate this config to change size, angle, opacity, flow, roundness, and other per-stamp behavior.

onMixinCanvas

Runs when the current stroke is composited onto the visible canvas. Return a canvas/context pair to replace or post-process the stroke canvas.

onEndStroke

Runs after a stroke is committed. Use it to reset cached stroke-local state.

Custom Module Example

import type { BrushBasicConfig, Module } from "fuderu";

class PressureColorModule implements Module {
onChangeConfig(config: BrushBasicConfig, pressure: number): void {
config.color = pressure > 0.5 ? "#111111" : "#888888";
}
}

brush.useModule(new PressureColorModule());

Built-In Module Configs

type JitterTrigger = "none" | "pressure";

interface DynamicShapeBasicConfig {
sizeJitter: number;
sizeJitterTrigger: JitterTrigger;
minDiameter: number;
angleJitter: number;
angleJitterTrigger: JitterTrigger;
roundJitter: number;
roundJitterTrigger: JitterTrigger;
minRoundness: number;
}
interface DynamicTransparencyBasicConfig {
opacityJitter: number;
opacityJitterTrigger: "none" | "pressure";
minOpacityJitter: number;
flowJitter: number;
flowJitterTrigger: "none" | "pressure";
minFlowJitter: number;
}
interface SpreadBasicConfig {
spreadRange: number;
spreadTrigger: "none" | "pressure";
count: number;
countJitter: number;
countJitterTrigger: "none" | "pressure";
}
interface PatternBasicConfig {
scale: number;
brightness: number;
contrast: number;
blendMode: CanvasRenderingContext2D["globalCompositeOperation"];
}

PatternModule.loadPattern(resource, canvasWidth, canvasHeight, tint?) accepts an image element, canvas element, or URL string. removePattern() clears the active texture.