UNPKG

@shopify/react-native-skia

Version:

High-performance React Native Graphics using Skia

83 lines (69 loc) 2.02 kB
import type { ReactNode } from "react"; import type { OpaqueRoot } from "react-reconciler"; import ReactReconciler from "react-reconciler"; import type { SkCanvas, Skia } from "../skia/types"; import { NodeType } from "../dom/types"; import { debug, sksgHostConfig } from "./HostConfig"; import type { Container } from "./StaticContainer"; import { createContainer } from "./Container"; import "./Elements"; const skiaReconciler = ReactReconciler(sksgHostConfig); // @ts-expect-error DefinitelyTyped is not up to date skiaReconciler.injectIntoDevTools(); export class SkiaSGRoot { private root: OpaqueRoot; private container: Container; constructor( public Skia: Skia, nativeId = -1 ) { const strictMode = false; this.container = createContainer(Skia, nativeId); this.root = skiaReconciler.createContainer( this.container, 0, null, strictMode, null, "", console.error, null ); } get sg() { const children = this.container.root; return { type: NodeType.Group, props: {}, children, isDeclaration: false }; } private updateContainer(element: ReactNode) { return new Promise((resolve) => { skiaReconciler.updateContainer(element, this.root, null, () => { resolve(true); }); }); } async render(element: ReactNode) { this.container.mount(); await this.updateContainer(element); this.container.redraw(); } drawOnCanvas(canvas: SkCanvas) { this.container.drawOnCanvas(canvas); } getPicture() { const recorder = this.Skia.PictureRecorder(); const canvas = recorder.beginRecording(); this.drawOnCanvas(canvas); const picture = recorder.finishRecordingAsPicture(); recorder.dispose(); return picture; } unmount() { this.container.unmount(); return new Promise((resolve) => { skiaReconciler.updateContainer(null, this.root, null, () => { debug("unmountContainer"); resolve(true); }); }); } }