Table of Contents

Class PathEffect

Namespace
Egami.Drawing
Assembly
Egami.Drawing.dll

Turns one path into another before it is filled or stroked: dashes, rounded corners, trimming, jitter, shapes stamped along the path, hatching. Effects are immutable, so one can be shared and reused; Then(PathEffect) and Plus(PathEffect) combine them. Apply one with Apply(PathEffect), or set it on Effect to have the canvas apply it before stroking. The set is Skia's: dash, corner, trim, discrete, 1D path, 2D line and 2D path effects, composed and summed.

public abstract record PathEffect : IEquatable<PathEffect>
Inheritance
PathEffect
Implements
Inherited Members

Examples

// A hand-drawn chart line: jittered the same way on every run, then its corners rounded.
Path data = Path.Polygon([new(10, 80), new(50, 30), new(90, 60), new(130, 20), new(170, 50)], close: false);
PathEffect sketchy = PathEffect.Jitter(segmentLength: 6, deviation: 1.5f, seed: 7).Then(PathEffect.Corner(3));
using Raster<Rgba8> chart = Raster.Create(180, 100, Rgba8.White);
using (RasterCanvas<Rgba8> canvas = chart.CreateCanvas())
{
    canvas.StrokePath(data, new Stroke(2) { Effect = sketchy }, new Rgba8(40, 40, 40, 255));

    // Dots along the line, and hatching inside a circle.
    canvas.FillPath(data.Apply(PathEffect.Stamp(Path.Circle(Vector2.Zero, 2), advance: 12, style: StampStyle.Translate)), Rgba8.Black);
    canvas.FillPath(Path.Circle(new Vector2(150, 75), 20).Apply(PathEffect.Hatch(Matrix3x2.CreateScale(1, 5) * Matrix3x2.CreateRotation(0.6f), width: 1)), Rgba8.Black);
}

// A line that draws itself: trim it to a growing fraction of its length, frame by frame.
Path frame30 = data.Apply(PathEffect.Trim(0, 0.3f));

Methods

Corner(float)

Returns an effect that rounds every corner between two straight lines with a quadratic curve that starts and ends radius from the corner (less on lines shorter than twice that), as Skia's corner effect does. Corners next to curves stay sharp.

public static PathEffect Corner(float radius)

Parameters

radius float

How far from each corner the rounding starts; 0 leaves the path as it is.

Returns

PathEffect

The effect.

Exceptions

ArgumentOutOfRangeException

radius is negative or not finite.

Dash(DashPattern)

Returns an effect that cuts a path into dashes, for paths that are filled or shapes that are not stroked; a stroke's own Dash is better for strokes, since vector backends keep it as data.

public static PathEffect Dash(DashPattern pattern)

Parameters

pattern DashPattern

The dashes.

Returns

PathEffect

The effect.

Hatch(Matrix3x2, float)

Returns an effect that hatches the area a path covers with parallel lines, as Skia's 2D line effect does: the lines are the rows through the centers of a lattice's cells (y = ½, 1½ and so on, and below), mapped into the path's space by lattice, cut where they leave the area by its fill rule. With a width, each line is outlined to it, so the result is filled; with width 0 the lines are left open, for a stroke to draw.

public static PathEffect Hatch(Matrix3x2 lattice, float width = 0)

Parameters

lattice Matrix3x2

The transform from lattice space, where rows are a unit apart, into the path's space: a scale sets the spacing, a rotation the angle.

width float

The width of the lines, or 0 for open lines.

Returns

PathEffect

The effect.

Exceptions

ArgumentException

lattice cannot be inverted.

ArgumentOutOfRangeException

width is negative or not finite.

HatchPath(Matrix3x2, Path)

Returns an effect that stamps a shape at every point of a lattice inside the area a path covers, as Skia's 2D path effect does. The result is the shapes, filled by the shape's fill rule.

public static PathEffect HatchPath(Matrix3x2 lattice, Path shape)

Parameters

lattice Matrix3x2

The transform from lattice space, where the points are the centers of the unit cells (x and y at a half), into the path's space.

shape Path

The shape, around its own origin, placed at each point.

Returns

PathEffect

The effect.

Exceptions

ArgumentException

lattice cannot be inverted.

Jitter(float, float, ulong)

Returns an effect that cuts each contour into straight pieces about segmentLength long and moves their ends across the path by up to deviation, for a hand-drawn look, as Skia's discrete effect does. The moves are a hash of the seed, the contour and the point, so the same path gives the same result on every thread and machine.

public static PathEffect Jitter(float segmentLength, float deviation, ulong seed = 0)

Parameters

segmentLength float

The length of the pieces.

deviation float

The largest move, either way.

seed ulong

The seed; another seed gives other moves.

Returns

PathEffect

The effect.

Exceptions

ArgumentOutOfRangeException

segmentLength is not positive, or a value is not finite.

Plus(PathEffect)

Returns an effect that draws the results of this one and of other together, as Skia's sum effect does.

public PathEffect Plus(PathEffect other)

Parameters

other PathEffect

The other effect.

Returns

PathEffect

The combined effect.

Stamp(Path, float, float, StampStyle)

Returns an effect that repeats a shape along each contour, every advance units, as Skia's 1D path effect does. The result is the shapes, filled by the shape's fill rule.

public static PathEffect Stamp(Path shape, float advance, float phase = 0, StampStyle style = StampStyle.Translate)

Parameters

shape Path

The shape, around its own origin, which goes on the path.

advance float

The distance between copies.

phase float

How far into the repeat each contour starts, as a dash pattern's phase is (and as Skia and PostScript read it): the first copy goes at the advance less the phase, modulo the advance.

style StampStyle

How each copy is placed.

Returns

PathEffect

The effect.

Exceptions

ArgumentOutOfRangeException

advance is not positive, or a value is not finite or defined.

Then(PathEffect)

Returns an effect that applies this one and then next to its result, as Skia's compose effect does.

public PathEffect Then(PathEffect next)

Parameters

next PathEffect

The effect applied second.

Returns

PathEffect

The combined effect.

Trim(float, float, bool)

Returns an effect that keeps the part of a path between two fractions of its total length, all contours counted in order, as Skia's trim effect does: animate the end from 0 to 1 and the path draws itself.

public static PathEffect Trim(float start, float end, bool inverted = false)

Parameters

start float

Where the kept part starts, from 0 to 1.

end float

Where it ends, from 0 to 1; nothing is kept when it is not after start.

inverted bool

Whether to keep the rest instead.

Returns

PathEffect

The effect.

Exceptions

ArgumentOutOfRangeException

start or end is outside 0 to 1.