Interfaces

CanvasProps

Properties

children?

optional children?: ReactNode;

colorSpace?

optional colorSpace?: ColorSpace;

The drawing surface's colour space. Defaults to 'srgb'.

'display-p3' creates a P3 surface, so wide-gamut images and gradients keep their colour on a P3 screen instead of being clamped. Note that a color prop is still carried as sRGB in the draw program, so color(display-p3 …) remains a compile-time conversion - this widens what images and gradients can show, not what a packed colour can express.

Read once, when the canvas mounts. The surface takes its colour space from the platform window, which is created with the view; changing this prop later warns in dev and does nothing. Remount with a key to change it.


composite?

optional composite?: "layer" | "texture";

How the canvas is composited on Android.

  • 'layer' (default) gives it its own compositor layer, which is fastest, but it punches through the window: React Native content behind the canvas does not show through its transparent pixels, and view transforms do not apply to it. Content drawn on top composites normally.
  • 'texture' draws the canvas inside the view hierarchy, so transparency and transforms behave like any other view, at the cost of a window redraw per frame.

Ignored on iOS, where the Metal layer already composites in-hierarchy.


debug?

optional debug?: boolean;

Device-pixel debugging overlay hook (reserved).


fonts?

optional fonts?: Record<string, FontSource[]>;

Fonts this canvas needs, useFonts' argument shape: { Family: [require('./Family-Regular.ttf'), ...] }.

The canvas registers them and withholds its children until every face is in, so text never flashes in the platform fallback - no hook, no gating in user code. Registration is process-wide and permanent, exactly as loadFonts does it; a failed load warns and renders anyway, since fallback text beats a canvas that stays blank forever.


opaque?

optional opaque?: boolean;

Render without an alpha channel: the layer composites without blending and the engine clears to opaque black. Anything behind the canvas stops showing through.

Measured neutral on a Mali-G68 with 400 animated shapes (main-thread FPS 57.5 → 56.7), so treat it as a correctness/appearance switch rather than an optimisation, and measure before enabling it for speed.


ref?

optional ref?: Ref<CanvasHandle>;

Imperative pixel readback: see CanvasHandle.


style?

optional style?: object;

viewport?

optional viewport?: 
  | Viewport
| SharedValueLike<Viewport>;

A root zoom/pan the renderer owns - see Viewport.

Applied above the whole draw program, so moving it never re-encodes the scene. A plain object is set from the commit. A SharedValue<Viewport> is pushed from the UI thread whenever it is written - a gesture worklet can drive it with no JS-thread hop and no React render. Drive it from one side or the other, not both.

On this page