Textures
In React Native Skia, Skia resources are shared across threads. We can use Reanimated to create textures on the UI thread, thus ensuring that we can display them on the onscreen canvas without needing to perform unnecessary copies.
useTexture
This hook allows you to allows you to create textures from React elements. It takes a React element and the dimensions of the texture as arguments and returns a Reanimated shared value that contains the texture.
tsx
import {useWindowDimensions } from "react-native";import {useTexture } from "@shopify/react-native-skia";import {Image ,Rect ,rect ,Canvas ,Fill } from "@shopify/react-native-skia";importReact from "react";constDemo = () => {const {width ,height } =useWindowDimensions ();consttexture =useTexture (<Fill color ="cyan" />,{width ,height });return (<Canvas style ={{flex : 1 }}><Image image ={texture }rect ={{x : 0,y : 0,width ,height }} /></Canvas >)}
tsx
import {useWindowDimensions } from "react-native";import {useTexture } from "@shopify/react-native-skia";import {Image ,Rect ,rect ,Canvas ,Fill } from "@shopify/react-native-skia";importReact from "react";constDemo = () => {const {width ,height } =useWindowDimensions ();consttexture =useTexture (<Fill color ="cyan" />,{width ,height });return (<Canvas style ={{flex : 1 }}><Image image ={texture }rect ={{x : 0,y : 0,width ,height }} /></Canvas >)}
useImageAsTexture
This hook allows you to upload an image to the GPU. It accepts an image source as argument. It will first load the image from its source and then upload it to the GPU.
tsx
import {useWindowDimensions } from "react-native";import {useImageAsTexture } from "@shopify/react-native-skia";import {Image ,Rect ,rect ,Canvas ,Fill } from "@shopify/react-native-skia";importReact from "react";constDemo = () => {const {width ,height } =useWindowDimensions ();consttexture =useImageAsTexture (require ("./assets/image.png"));return (<Canvas style ={{flex : 1 }}><Image image ={texture }rect ={{x : 0,y : 0,width ,height }} /></Canvas >)}
tsx
import {useWindowDimensions } from "react-native";import {useImageAsTexture } from "@shopify/react-native-skia";import {Image ,Rect ,rect ,Canvas ,Fill } from "@shopify/react-native-skia";importReact from "react";constDemo = () => {const {width ,height } =useWindowDimensions ();consttexture =useImageAsTexture (require ("./assets/image.png"));return (<Canvas style ={{flex : 1 }}><Image image ={texture }rect ={{x : 0,y : 0,width ,height }} /></Canvas >)}
usePictureAsTexture
The hook allows you to create a texture from an SkPicture
.
This is useful to either generate the drawing commands outside the React lifecycle or using the imperative API to build a texture.
tsx
import {useWindowDimensions } from "react-native";import {usePictureAsTexture } from "@shopify/react-native-skia";import {Image ,Rect ,rect ,Canvas ,Fill ,Skia } from "@shopify/react-native-skia";importReact from "react";constrec =Skia .PictureRecorder ();constcanvas =rec .beginRecording ();canvas .drawColor (Skia .Color ("cyan"));constpicture =rec .finishRecordingAsPicture ();constDemo = () => {const {width ,height } =useWindowDimensions ();consttexture =usePictureAsTexture (picture ,{width ,height });return (<Canvas style ={{flex : 1 }}><Image image ={texture }rect ={{x : 0,y : 0,width ,height }} /></Canvas >)}
tsx
import {useWindowDimensions } from "react-native";import {usePictureAsTexture } from "@shopify/react-native-skia";import {Image ,Rect ,rect ,Canvas ,Fill ,Skia } from "@shopify/react-native-skia";importReact from "react";constrec =Skia .PictureRecorder ();constcanvas =rec .beginRecording ();canvas .drawColor (Skia .Color ("cyan"));constpicture =rec .finishRecordingAsPicture ();constDemo = () => {const {width ,height } =useWindowDimensions ();consttexture =usePictureAsTexture (picture ,{width ,height });return (<Canvas style ={{flex : 1 }}><Image image ={texture }rect ={{x : 0,y : 0,width ,height }} /></Canvas >)}
Under the hood
Reanimated 2 provides a runOnUI
function that enables the execution of JavaScript code on the UI thread. This function is particularly useful for creating GPU textures that can be rendered directly onto an onscreen canvas.
tsx
import {useEffect } from "react";import {runOnUI ,useSharedValue } from "react-native-reanimated";import type {SharedValue } from "react-native-reanimated";import {Skia ,Canvas ,Image } from "@shopify/react-native-skia";import type {SkImage } from "@shopify/react-native-skia";constcreateTexture = (image :SharedValue <SkImage | null>) => {"worklet";constsurface =Skia .Surface .MakeOffscreen (200, 200)!;constcanvas =surface .getCanvas ();canvas .drawColor (Skia .Color ("cyan"));surface .flush ();image .value =surface .makeImageSnapshot ();}constDemo = () => {constimage =useSharedValue <SkImage | null>(null);useEffect (() => {runOnUI (createTexture )(image );}, []);return (<Canvas style ={{flex : 1 }}><Image image ={image }x ={0}y ={0}width ={200}height ={200} /></Canvas >);};
tsx
import {useEffect } from "react";import {runOnUI ,useSharedValue } from "react-native-reanimated";import type {SharedValue } from "react-native-reanimated";import {Skia ,Canvas ,Image } from "@shopify/react-native-skia";import type {SkImage } from "@shopify/react-native-skia";constcreateTexture = (image :SharedValue <SkImage | null>) => {"worklet";constsurface =Skia .Surface .MakeOffscreen (200, 200)!;constcanvas =surface .getCanvas ();canvas .drawColor (Skia .Color ("cyan"));surface .flush ();image .value =surface .makeImageSnapshot ();}constDemo = () => {constimage =useSharedValue <SkImage | null>(null);useEffect (() => {runOnUI (createTexture )(image );}, []);return (<Canvas style ={{flex : 1 }}><Image image ={image }x ={0}y ={0}width ={200}height ={200} /></Canvas >);};
This example demonstrates how to create a texture, draw a cyan color onto it, and then display it using the Image
component from @shopify/react-native-skia
. The runOnUI
function ensures that the texture creation and drawing operations are performed on the UI thread for optimal performance.
Make sure that you have installed the necessary packages and configured your project to use Reanimated 2 and @shopify/react-native-skia
before running this code.