Skip to main content
The Paint component controls how shapes and other drawing elements are rendered. It defines styling properties like color, opacity, blend modes, and effects.

Basic Usage

import { Canvas, Circle, Paint } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Paint color="blue" opacity={0.5} />
  <Circle cx={100} cy={100} r={50} />
</Canvas>

Props

Color and Opacity

color
Color
Sets the color for drawing operations. Accepts:
  • Named colors: "red", "blue", etc.
  • Hex colors: "#FF0000", "#F00"
  • RGB/RGBA: "rgb(255, 0, 0)", "rgba(255, 0, 0, 0.5)"
  • HSL/HSLA: "hsl(0, 100%, 50%)"
opacity
number
Alpha value from 0 (fully transparent) to 1 (fully opaque)

Style

style
'fill' | 'stroke'
default:"'fill'"
Whether to fill or stroke shapes:
  • fill: Fills the interior of shapes
  • stroke: Draws only the outline

Stroke Properties

strokeWidth
number
default:"1"
Width of strokes in pixels
strokeCap
'butt' | 'round' | 'square'
default:"'butt'"
How line ends are drawn:
  • butt: Flat end at the endpoint
  • round: Rounded end extending past the endpoint
  • square: Square end extending past the endpoint
strokeJoin
'miter' | 'round' | 'bevel'
default:"'miter'"
How corners are drawn:
  • miter: Sharp corner
  • round: Rounded corner
  • bevel: Beveled corner
strokeMiter
number
default:"4"
Limit for miter joins before beveling

Blend Mode

blendMode
BlendMode
default:"'srcOver'"
How colors are composited. Common values:
  • srcOver: Default alpha blending
  • multiply: Multiplies colors
  • screen: Inverted multiply
  • overlay: Combination of multiply and screen
  • darken, lighten, colorDodge, colorBurn, etc.
See Blend Modes for complete list.

Effects and Filters

antiAlias
boolean
default:"true"
Enable anti-aliasing for smoother edges
dither
boolean
default:"false"
Enable dithering to reduce color banding

Applying Effects

The Paint component can contain child components that add effects:

Shaders

import { Canvas, Circle, Paint, LinearGradient, vec } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={150} cy={150} r={100}>
    <Paint>
      <LinearGradient
        start={vec(0, 0)}
        end={vec(300, 300)}
        colors={["red", "blue"]}
      />
    </Paint>
  </Circle>
</Canvas>

Image Filters

import { Canvas, Circle, Paint, Blur } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={150} cy={150} r={100} color="purple">
    <Paint>
      <Blur blur={10} />
    </Paint>
  </Circle>
</Canvas>

Color Filters

import { Canvas, Rect, Paint, ColorMatrix } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Rect x={50} y={50} width={200} height={200} color="green">
    <Paint>
      <ColorMatrix
        matrix={[
          0.95, 0, 0, 0, 0,
          0, 0.65, 0, 0, 0,
          0, 0, 0.85, 0, 0,
          0, 0, 0, 1, 0,
        ]}
      />
    </Paint>
  </Rect>
</Canvas>

Examples

Stroked Shape

import { Canvas, Rect, Paint } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Rect x={50} y={50} width={200} height={200}>
    <Paint
      style="stroke"
      strokeWidth={5}
      strokeCap="round"
      strokeJoin="round"
      color="blue"
    />
  </Rect>
</Canvas>

Semi-Transparent Fill

<Circle cx={150} cy={150} r={100}>
  <Paint color="red" opacity={0.5} />
</Circle>

Blend Mode Effect

import { Canvas, Circle, Paint } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={120} cy={150} r={80} color="red" />
  <Circle cx={180} cy={150} r={80}>
    <Paint color="blue" blendMode="multiply" />
  </Circle>
</Canvas>

Multiple Effects

import { Canvas, Rect, Paint, Blur, ColorMatrix } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Rect x={50} y={50} width={200} height={200}>
    <Paint opacity={0.8}>
      <Blur blur={5} />
      <ColorMatrix
        matrix={[
          1, 0, 0, 0, 0,
          0, 1, 0, 0, 0,
          0, 0, 1, 0, 0,
          0, 0, 0, 0.5, 0,
        ]}
      />
    </Paint>
  </Rect>
</Canvas>

Gradient with Stroke

import { Canvas, Path, Paint, LinearGradient, vec } from "@shopify/react-native-skia";

const path = "M 50 150 Q 100 50 150 150 T 250 150";

<Canvas style={{ flex: 1 }}>
  <Path path={path}>
    <Paint style="stroke" strokeWidth={10} strokeCap="round">
      <LinearGradient
        start={vec(50, 0)}
        end={vec(250, 0)}
        colors={["purple", "orange", "cyan"]}
      />
    </Paint>
  </Path>
</Canvas>

Imperative API

You can also create paint objects imperatively:
import { Skia, PaintStyle, StrokeCap, StrokeJoin } from "@shopify/react-native-skia";

const paint = Skia.Paint();
paint.setColor(Skia.Color("blue"));
paint.setStyle(PaintStyle.Stroke);
paint.setStrokeWidth(5);
paint.setStrokeCap(StrokeCap.Round);
paint.setStrokeJoin(StrokeJoin.Round);
paint.setAlphaf(0.8);

// Use with imperative drawing
const onDraw = (canvas) => {
  canvas.drawCircle(150, 150, 100, paint);
};

Paint Methods

setColor
(color: SkColor) => void
Sets the paint color
setAlphaf
(alpha: number) => void
Sets alpha value (0-1)
setStyle
(style: PaintStyle) => void
Sets fill or stroke style
setStrokeWidth
(width: number) => void
Sets stroke width
setStrokeCap
(cap: StrokeCap) => void
Sets stroke cap style
setStrokeJoin
(join: StrokeJoin) => void
Sets stroke join style
setStrokeMiter
(miter: number) => void
Sets miter limit
setBlendMode
(mode: BlendMode) => void
Sets blend mode
setAntiAlias
(aa: boolean) => void
Enables/disables anti-aliasing
setDither
(dither: boolean) => void
Enables/disables dithering
setShader
(shader: SkShader | null) => void
Sets a shader for gradients or patterns
setImageFilter
(filter: SkImageFilter | null) => void
Sets an image filter (blur, etc.)
setColorFilter
(filter: SkColorFilter | null) => void
Sets a color filter
setMaskFilter
(filter: SkMaskFilter | null) => void
Sets a mask filter
setPathEffect
(effect: SkPathEffect | null) => void
Sets a path effect (dash, etc.)
copy
() => SkPaint
Creates a copy of the paint
reset
() => void
Resets paint to default values

Performance Tips

  • Reuse paint objects when possible
  • Avoid creating new paint instances in render methods
  • Use useMemo for paint configurations that don’t change
  • Simple fills are faster than strokes
  • Anti-aliasing has a small performance cost

Build docs developers (and LLMs) love