Documentation Index
Fetch the complete documentation index at: https://mintlify.com/shopify/react-native-skia/llms.txt
Use this file to discover all available pages before exploring further.
Path effects modify how paths are rendered, allowing you to create dashed lines, rounded corners, discrete segments, and pattern-based effects.
DashPathEffect
Create dashed or dotted lines.
| Name | Type | Description |
|---|
| intervals | number[] | Array of on/off lengths |
| phase | number | Offset into intervals (default: 0) |
| children | ReactNode | Content to apply effect to |
import { Canvas, Path, DashPathEffect, Skia } from "@shopify/react-native-skia";
const DashDemo = () => {
const path = Skia.Path.Make();
path.moveTo(20, 20);
path.lineTo(236, 236);
return (
<Canvas style={{ flex: 1 }}>
<Path
path={path}
color="black"
style="stroke"
strokeWidth={4}
>
<DashPathEffect intervals={[10, 10]} />
</Path>
</Canvas>
);
};
Dash Patterns
Simple Dash
// 10px dash, 10px gap
<DashPathEffect intervals={[10, 10]} />
Dot Pattern
// 2px dot, 8px gap
<DashPathEffect intervals={[2, 8]} />
Complex Pattern
// Long dash, short gap, short dash, short gap (repeating)
<DashPathEffect intervals={[20, 5, 5, 5]} />
Animated Dash
Use the phase property to animate dashes:
import { Canvas, Path, DashPathEffect } from "@shopify/react-native-skia";
import { useSharedValue, withRepeat, withTiming } from "react-native-reanimated";
import { useEffect } from "react";
const AnimatedDashDemo = () => {
const phase = useSharedValue(0);
useEffect(() => {
phase.value = withRepeat(withTiming(20, { duration: 1000 }), -1, false);
}, [phase]);
return (
<Canvas style={{ flex: 1 }}>
<Path path={myPath} color="black" style="stroke" strokeWidth={4}>
<DashPathEffect intervals={[10, 10]} phase={phase} />
</Path>
</Canvas>
);
};
CornerPathEffect
Round sharp corners in paths.
| Name | Type | Description |
|---|
| r | number | Corner radius |
| children | ReactNode | Content to apply effect to |
import { Canvas, Path, CornerPathEffect, Skia } from "@shopify/react-native-skia";
const CornerDemo = () => {
const path = Skia.Path.Make();
path.moveTo(50, 50);
path.lineTo(200, 50);
path.lineTo(200, 200);
path.lineTo(50, 200);
return (
<Canvas style={{ flex: 1 }}>
<Path
path={path}
color="blue"
style="stroke"
strokeWidth={4}
>
<CornerPathEffect r={20} />
</Path>
</Canvas>
);
};
DiscretePathEffect
Break paths into random discrete segments.
| Name | Type | Description |
|---|
| length | number | Segment length |
| deviation | number | Random deviation amount |
| seed | number | Random seed (default: 0) |
| children | ReactNode | Content to apply effect to |
import { Canvas, Path, DiscretePathEffect, Skia } from "@shopify/react-native-skia";
const DiscreteDemo = () => {
const path = Skia.Path.Make();
path.moveTo(20, 128);
path.lineTo(236, 128);
return (
<Canvas style={{ flex: 1 }}>
<Path
path={path}
color="red"
style="stroke"
strokeWidth={2}
>
<DiscretePathEffect length={10} deviation={4} seed={42} />
</Path>
</Canvas>
);
};
Great for creating hand-drawn or sketchy effects:
import { Canvas, Circle, DiscretePathEffect } from "@shopify/react-native-skia";
const SketchyCircle = () => {
return (
<Canvas style={{ flex: 1 }}>
<Circle
cx={128}
cy={128}
r={64}
color="black"
style="stroke"
strokeWidth={2}
>
<DiscretePathEffect length={5} deviation={2} />
</Circle>
</Canvas>
);
};
Path1DPathEffect
Stamp a path repeatedly along another path.
| Name | Type | Description |
|---|
| path | SkPath | Path to stamp |
| advance | number | Distance between stamps |
| phase | number | Offset along path |
| style | Path1DEffectStyle | Stamping style |
| children | ReactNode | Content to apply effect to |
import {
Canvas,
Path,
Path1DPathEffect,
Skia
} from "@shopify/react-native-skia";
const Path1DDemo = () => {
// Create the main path
const mainPath = Skia.Path.Make();
mainPath.moveTo(20, 128);
mainPath.quadTo(128, 50, 236, 128);
// Create the stamp (a small arrow)
const stamp = Skia.Path.Make();
stamp.moveTo(0, -5);
stamp.lineTo(10, 0);
stamp.lineTo(0, 5);
return (
<Canvas style={{ flex: 1 }}>
<Path
path={mainPath}
color="blue"
style="stroke"
strokeWidth={2}
>
<Path1DPathEffect
path={stamp}
advance={30}
phase={0}
style="rotate"
/>
</Path>
</Canvas>
);
};
Path1D Styles
"translate" - Stamps are only translated
"rotate" - Stamps rotate to follow the path
"morph" - Stamps morph to follow the path
Path2DPathEffect
Stamp a path in a 2D grid pattern.
| Name | Type | Description |
|---|
| matrix | SkMatrix | Transformation matrix for grid |
| path | SkPath | Path to stamp |
| children | ReactNode | Content to apply effect to |
import { Canvas, Rect, Path2DPathEffect, Skia } from "@shopify/react-native-skia";
const Path2DDemo = () => {
// Create stamp (a small circle)
const stamp = Skia.Path.Make();
stamp.addCircle(0, 0, 3);
// Create grid matrix (20px spacing)
const matrix = Skia.Matrix();
matrix.translate(20, 20);
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256} color="blue">
<Path2DPathEffect matrix={matrix} path={stamp} />
</Rect>
</Canvas>
);
};
Line2DPathEffect
Create a pattern of lines.
| Name | Type | Description |
|---|
| width | number | Line width |
| matrix | SkMatrix | Grid transformation |
| children | ReactNode | Content to apply effect to |
import { Canvas, Rect, Line2DPathEffect, Skia } from "@shopify/react-native-skia";
const Line2DDemo = () => {
const matrix = Skia.Matrix();
matrix.translate(10, 10);
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256} color="black">
<Line2DPathEffect width={2} matrix={matrix} />
</Rect>
</Canvas>
);
};
Combining Path Effects
Path effects can be combined by nesting them. The innermost effect is applied first:
import {
Canvas,
Path,
DashPathEffect,
CornerPathEffect,
DiscretePathEffect
} from "@shopify/react-native-skia";
const CombinedEffectsDemo = () => {
return (
<Canvas style={{ flex: 1 }}>
<Path path={myPath} color="blue" style="stroke" strokeWidth={3}>
{/* Applied first: round corners */}
<CornerPathEffect r={10}>
{/* Applied second: make sketchy */}
<DiscretePathEffect length={5} deviation={2}>
{/* Applied last: dash the result */}
<DashPathEffect intervals={[15, 5]} />
</DiscretePathEffect>
</CornerPathEffect>
</Path>
</Canvas>
);
};
Sum Path Effect
The Sum component applies multiple path effects in parallel and combines the results:
import { Canvas, Path, Sum, DashPathEffect, DiscretePathEffect } from "@shopify/react-native-skia";
const SumDemo = () => {
return (
<Canvas style={{ flex: 1 }}>
<Path path={myPath} color="red" style="stroke" strokeWidth={2}>
<Sum>
<DashPathEffect intervals={[10, 10]} />
<DiscretePathEffect length={5} deviation={2} />
</Sum>
</Path>
</Canvas>
);
};
Imperative API
Create path effects imperatively:
import { Skia, Path1DEffectStyle } from "@shopify/react-native-skia";
// Dash effect
const dashEffect = Skia.PathEffect.MakeDash([10, 10], 0);
// Corner effect
const cornerEffect = Skia.PathEffect.MakeCorner(20);
// Discrete effect
const discreteEffect = Skia.PathEffect.MakeDiscrete(10, 4, 42);
// Compose effects
const composedEffect = Skia.PathEffect.MakeCompose(dashEffect, cornerEffect);
const paint = Skia.Paint();
paint.setPathEffect(composedEffect);
Common Use Cases
Dashed Border
<RoundedRect x={50} y={50} width={156} height={156} r={10} color="blue" style="stroke" strokeWidth={2}>
<DashPathEffect intervals={[8, 4]} />
</RoundedRect>
Hand-Drawn Effect
<Path path={myPath} color="black" style="stroke" strokeWidth={2}>
<DiscretePathEffect length={3} deviation={1.5} />
</Path>
Animated Dash Border
const phase = useSharedValue(0);
useEffect(() => {
phase.value = withRepeat(withTiming(40, { duration: 2000 }), -1, false);
}, []);
return (
<Rect x={10} y={10} width={236} height={236} color="blue" style="stroke" strokeWidth={3}>
<DashPathEffect intervals={[20, 20]} phase={phase} />
</Rect>
);