Export

Snapshots, offscreen rendering, PDF and SVG.

Snapshot a live canvas

const canvas = useRef<CanvasHandle>(null)

async function exportCanvas() {
  if (canvas.current == null) return
  const shot = await canvas.current.snapshot()   // Snapshot
  await canvas.current.save('/absolute/path/out.png')
}

snapshot returns a Snapshot: PNG/JPEG/WebP bytes, or straight-alpha RGBA8888 rows for format: 'raw', in an ArrayBuffer. save writes the file natively.

SnapshotOptions · SnapshotFormat

Colour

Encoded snapshots keep the canvas colour profile, also when scaled.

Offscreen

renderToImage renders without a canvas (RenderToImageOptions). Like renderToSvg and renderToPdf, it takes JSX, a SceneNode[] or a Scene:

const image = await renderToImage(
  <Rect x={0} y={0} width={512} height={512}>
    <LinearGradient start={{ x: 0, y: 0 }} end={{ x: 512, y: 512 }} colors={['#f0f', '#0ff']} />
  </Rect>,
  { width: 512, height: 512 }
)

renderToPdf pages can mix element and scene.

Retained surface

createOffscreenSurface keeps a GPU surface and its program alive between renders:

const surface = createOffscreenSurface({ width: 1024, height: 1024 })
scene.attach(surface)                 // a surface is a scene target, like a view

for (let f = 0; f < 120; f++) {
  t.set({ x: f * 4 })                 // slot write - no re-encode
  surface.flush()                     // render on the offscreen worker
  if (f % 30 === 0) await surface.save(`${dir}/frame-${f}.png`)
}
const still = await surface.toImage() // readback only when asked
surface.dispose()                     // GPU memory is explicit-lifetime

setViewport([zoom, x, y]) crops and zooms the export. hitTest(x, y, precise) works headless. The colour space is fixed at creation. For a single export, renderToImage is cheaper.

colorSpace picks the output space, as on a <Canvas>:

const wide = await renderToImage(<Chart data={data} />, {
  width: 512,
  height: 512,
  colorSpace: 'display-p3',
})

Match it to the canvas the image will be drawn on.

useOffscreenImage is the hook form:

const badge = useOffscreenImage(<Badge count={n} />, { width: 64, height: 64 }, [n])

PDF

await renderToPdf(
  `${RNFS.DocumentDirectoryPath}/report.pdf`,
  [
    { width: 612, height: 792, element: <Cover /> },
    { width: 612, height: 792, element: <Chart data={data} /> },
  ],
  { title: 'Quarterly report', author: 'Acme' }
)

PdfPage · PdfMetadata · useOffscreenPdf → PdfExportState

SVG

const svg = await renderToSvg(<Chart data={data} />, { width: 400, height: 300 })

RenderToSvgOptions · useOffscreenSvg

On this page