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.
Anytime you draw something in Skia, you specify painting attributes like color, blend mode, or style. These attributes control how shapes, text, and images appear on the canvas.
Applying Paint Attributes
Paint attributes can be applied in three ways:
- As properties on drawing components or groups
- As children of drawing components or groups
- Via Paint component reference for manual assignment
Property-Based Attributes
These attributes can be set directly as props:
Child-Based Attributes
These attributes are applied as children:
Fills and Strokes
In Skia, paint has a style property indicating whether it’s a fill or stroke. You can apply multiple paints to a single shape:
import { Canvas, Circle, Paint, vec } from "@shopify/react-native-skia";
const width = 256;
const height = 256;
const PaintDemo = () => {
const strokeWidth = 10;
const c = vec(width / 2, height / 2);
const r = (width - strokeWidth) / 2;
return (
<Canvas style={{ width, height }}>
<Circle c={c} r={r}>
<Paint color="lightblue" />
<Paint color="#adbce6" style="stroke" strokeWidth={strokeWidth} />
<Paint color="#ade6d8" style="stroke" strokeWidth={strokeWidth / 2} />
</Circle>
</Canvas>
);
};
This circle has:
- One light blue fill
- Two different stroke paints with different colors and widths
Inheritance
Descendants inherit paint attributes from their ancestors:
import { Canvas, Circle, Group } from "@shopify/react-native-skia";
const width = 256;
const height = 256;
const PaintDemo = () => {
const r = width / 6;
return (
<Canvas style={{ width, height }}>
<Group color="lightblue">
<Circle cx={r} cy={r} r={r} />
<Group style="stroke" strokeWidth={10}>
<Circle cx={3 * r} cy={3 * r} r={r} />
</Group>
</Group>
</Canvas>
);
};
- The first circle inherits the
lightblue color as a fill
- The second circle inherits both the color and the stroke styling
Complex Paint Attributes
Shaders and filters are passed as children:
import { Canvas, Circle, LinearGradient, vec } from "@shopify/react-native-skia";
const width = 256;
const height = 256;
const PaintDemo = () => {
const r = width / 2;
return (
<Canvas style={{ width, height }}>
<Circle cx={r} cy={r} r={r}>
<LinearGradient
start={vec(0, 0)}
end={vec(2 * r, 2 * r)}
colors={["#00ff87", "#60efff"]}
/>
</Circle>
</Canvas>
);
};
Inherited Complex Attributes
Complex attributes also inherit:
import { Canvas, Circle, Group, LinearGradient, vec } from "@shopify/react-native-skia";
const width = 256;
const height = 256;
const PaintDemo = () => {
const r = width / 2;
return (
<Canvas style={{ width, height }}>
<Group>
<LinearGradient
start={vec(0, 0)}
end={vec(2 * r, 2 * r)}
colors={["#0061ff", "#60efff"]}
/>
<Circle cx={r} cy={r} r={r} />
<Circle cx={3 * r} cy={r} r={r / 2} />
</Group>
</Canvas>
);
};
Manual Paint Assignment
For advanced use cases, create paint instances manually:
import { Canvas, Circle, Skia } from "@shopify/react-native-skia";
const width = 256;
const height = 256;
const r = width / 2;
// Create paint instance
const paint = Skia.Paint();
paint.setColor(Skia.Color("lightblue"));
paint.setAntiAlias(true);
const PaintDemo = () => {
return (
<Canvas style={{ flex: 1 }}>
<Circle paint={paint} cx={r} cy={r} r={r} />
</Canvas>
);
};
Common Patterns
Multiple Fills with Opacity
import { Canvas, Rect, Paint } from "@shopify/react-native-skia";
const LayeredFills = () => (
<Canvas style={{ width: 256, height: 256 }}>
<Rect x={50} y={50} width={156} height={156}>
<Paint color="red" opacity={0.5} />
<Paint color="blue" opacity={0.5} />
</Rect>
</Canvas>
);
Stroke Over Fill
import { Canvas, Circle, Paint } from "@shopify/react-native-skia";
const StrokedCircle = () => (
<Canvas style={{ width: 256, height: 256 }}>
<Circle cx={128} cy={128} r={100}>
<Paint color="#e3f2fd" />
<Paint color="#2196f3" style="stroke" strokeWidth={4} />
</Circle>
</Canvas>
);
Gradient with Stroke
import { Canvas, Rect, Paint, LinearGradient, vec } from "@shopify/react-native-skia";
const GradientRect = () => (
<Canvas style={{ width: 256, height: 256 }}>
<Rect x={50} y={50} width={156} height={156}>
<LinearGradient
start={vec(50, 50)}
end={vec(206, 206)}
colors={["#667eea", "#764ba2"]}
/>
<Paint style="stroke" strokeWidth={2} color="white" />
</Rect>
</Canvas>
);
Multiple Strokes
import { Canvas, Circle, Paint } from "@shopify/react-native-skia";
const MultiStroke = () => (
<Canvas style={{ width: 256, height: 256 }}>
<Circle cx={128} cy={128} r={100}>
<Paint color="white" />
<Paint color="#000" style="stroke" strokeWidth={10} />
<Paint color="#fff" style="stroke" strokeWidth={6} />
<Paint color="#000" style="stroke" strokeWidth={2} />
</Circle>
</Canvas>
);
Paint Priority
When multiple paint attributes are specified:
- Direct props on the component have highest priority
- Paint children are applied in order
- Inherited attributes from parent groups apply if not overridden
import { Canvas, Circle, Group, Paint } from "@shopify/react-native-skia";
const PaintPriority = () => (
<Canvas style={{ width: 256, height: 256 }}>
<Group color="red">
<Circle cx={64} cy={128} r={50} /> {/* Red (inherited) */}
<Circle cx={128} cy={128} r={50} color="blue" /> {/* Blue (prop) */}
<Circle cx={192} cy={128} r={50}>
<Paint color="green" /> {/* Green (child) */}
</Circle>
</Group>
</Canvas>
);
- Reuse paint instances when possible
- Use groups to apply common attributes to multiple shapes
- Avoid creating new paint objects every render
- Cache color values that don’t change
- Use simple blend modes for better performance
See Also