Skip to main content
Technical preview

Redraw is currently in technical preview, available to start-react-native.dev subscribers. API is unstable.

Stroke Effects

Stroke effects modify how a stroke renders without changing its color or width; they decorate, replicate, or geometrically alter the stroke band. Pass them as the third argument to brush.addStroke(color, width, effects):

import { Brush, Dash } from "redraw";

const brush = new Brush();
brush.addStroke("#222", 8, new Dash(20, 10));

effects can be a single node or an array of them. They live in packages/redraw/src/nodes/brushes/StrokeEffect.ts.

Dash

Standard dashed stroke.

Dash
new Dash(dashLength, gapLength);
new Dash(dashLength, gapLength, offset);
new Dash(dashLength, gapLength, { offset, cap, pathLength });
ParamTypeWhat it controls
dashLengthnumberPainted segment length.
gapLengthnumberGap between segments.
offsetnumber (or options.offset)Phase shift; animate to make dashes travel.
cap"butt" | "round"Sharp ends vs rounded.
pathLengthnumberOverride; used for arc-length parameterization.

With cap: "round":

Dash with round caps

Outline

Concentric outlines around the stroke at fixed spacing.

Outline
new Outline(count, spacing, baseWidth);
ParamTypeWhat it controls
countnumberHow many rings to emit.
spacingnumberDistance between consecutive rings.
baseWidthnumberWidth of each individual ring.

InnerStroke / OuterStroke

Restrict the stroke to one side of the SDF boundary.

InnerOuter
InnerStrokeOuterStroke
new InnerStroke(strokeWidth); // only inside (sdf < 0)
new OuterStroke(strokeWidth); // only outside (sdf > 0)
ParamTypeWhat it controls
strokeWidthnumberStroke band width.

OffsetStroke

Stroke offset from the boundary; positive offset pushes outward, negative inward.

Outward (offset > 0)Inward (offset < 0)
OffsetStroke outwardOffsetStroke inward
new OffsetStroke(strokeWidth, offset);
ParamTypeWhat it controls
strokeWidthnumberStroke band width.
offsetnumberDistance from the boundary; sign decides side.

DoubleStroke

Two parallel strokes with a gap between them.

DoubleStroke
new DoubleStroke(strokeWidth, gap);
ParamTypeWhat it controls
strokeWidthnumberWidth of each individual stroke.
gapnumberDistance between the two strokes.

Total visual width is 2 × strokeWidth + gap.

WavyStroke

Sinusoidal wobble perpendicular to the stroke. Animate phase to make the wave travel.

WavyStroke
new WavyStroke(strokeWidth, amplitude, frequency, phase = 0);
ParamTypeWhat it controls
strokeWidthnumberWidth of the wavy stroke band.
amplitudenumberPeak displacement perpendicular to the path.
frequencynumberCycles per arc-length unit.
phasenumberPhase offset; animate to make the wave move.

Dotted

Circular dots placed along the path at regular spacing.

Dotted
new Dotted(dotRadius, spacing, pathLength, offset = 0);
ParamTypeWhat it controls
dotRadiusnumberRadius of each dot.
spacingnumberDistance between consecutive dot centers.
pathLengthnumberTotal arc length, needed for parameterization.
offsetnumberPhase shift; animate to make dots travel.

pathLength is mandatory because dotted spacing is in arc-length, not screen units. Get it via path.length() after fitting:

const pathGeo = fitPath(svgString, w, h);
const dotted = new Dotted(4, 12, pathGeo.length());

Taper

Linear width transition from startWidth to endWidth along the path.

Taper
new Taper(startWidth, endWidth, taperStart = 0, taperEnd = 0);
ParamTypeWhat it controls
startWidthnumberWidth at ctx.t = 0.
endWidthnumberWidth at ctx.t = 1.
taperStartnumberSmoothstep ramp at the start (0..1).
taperEndnumberSmoothstep ramp at the end (0..1).

For animated tapers (a head that retracts as you draw), use the TaperedTip width preset on Stroke Widths; it pairs with path.segment(...).

Combining effects

Most effects can stack. Pass an array as the third argument:

brush.addStroke("#222", 8, [
new Dash(20, 10),
new Outline(2, 4, 1),
]);

Order matters; effects compose left-to-right.