Introduction to React Native Skia



Introduction
Hi there, My name is Darshan. Welcome to my personal blog site. I usually write about Mobile/Web Engineering. Today, I am going to cover an introduction to the library called React Native Skia. A new way to render 2D graphics up to 60 FPS.
This is a very beginner-friendly blog that will help you to get familiar with React Native Skia and its APIs.
What is Skia?
Skia is an engine mainly used inside browsers and frameworks like Flutter to render 2D graphics. It uses GPU to render graphics, and that's one reason it's so performant. React Native Skia provides a JavaScript API that communicates with Native Skia engines, enabling us to render 2D graphics on the GPU. It's very similar to HTML5 Canvas. Thanks to the Shopify team for making this possible.
Installation
Enough talk, let's install this library in our React Native project by following the official documentation.
You can install this project in both bare React Native CLI and Expo. For the sake of this blog, we are using Expo to make things simpler, but you are free to use React Native CLI project. You have to follow the installation steps for the native environment to make it work.
npm install @shopify/react-native-skia
Understanding the APIs
Canvas
So I am excited to render some graphics but where? Like React Native View
, it has a Canvas
API that lets you draw anything.
Everything inside the canvas is considered as pixels; you can paint pixels, you can move certain elements by pixels. The mental model behind understanding this is very similar to HTML5 Canvas.
You can add a style
prop like View
. We are using flex
as 1
to make sure this canvas container fills the available space.
You can learn more about the canvas here.
import { Canvas } from "@shopify/react-native-skia"; export default function App() { return <Canvas style={{ flex: 1 }}></Canvas>; }
The beauty of React Native Skia is that the APIs are much declarative like the React Ecosystem, that opens door to lots of creative stuff.
Drawing a Shape
Since we have the canvas ready let's try to draw something. Let's start with adding a square shape.
We can import a component Rect
that will draw a rectangle but hold on we need to define the structure of that rectangle such as its height, width, x, y. In order to achieve this, we have to use the rect
function that will define this structure.
The rect
function takes 4 arguments followed by height
, width
, x
, and y
. Let's use this function to implement a rectangle.
The color
prop as you have guessed it, specifies the color of that shape. You can decide whether you want to fill the color or provide it as a strokeColor. By default, it fills the shape.
import { Canvas, Rect, rect } from "@shopify/react-native-skia"; export default function App() { return <Canvas style={{ flex: 1 }}> <Rect rect={rect(100, 100, 50, 200)} color="red" > </Canvas>; }
I have given a random x
and y
position so the rectangle should be visible somewhere in the middle of the screen. Good start.
Like Rect, it also has a Circle
you can play more with shapes. Follow this documentation to deep dive.
Image
Like HTML5 canvas, you can draw images using the Image
API.
Before we can draw the image, we have to load that image first, using useImage
hook we can draw the image.
This hook returns a Skia image that we can pass to the Image
component.
import { useImage, Image } from "@shopify/react-native-skia"; const ImageDemo = () => { // loading image from the local directory const image = useImage(require("./assets/images/star.png")); // make sure the image is being loaded properly. if (!image) return null; return ( <Canvas style={{ flex: 1 }}> <Image image={image} x={0} y={0} width={256} height={256} /> </Canvas> ); };
You can also specify height
, width
, and coordinates like x
and y
.
Animations
Rendering graphics on canvas is cool but what if you can also animate those elements. We can use react-native-reanimated
library to animate elements like Rect
and Image
same as React Native View
components.
In this example let's animate the radius of the circle. We will create a breath in/out animation.
import { useEffect } from "react"; import { Canvas, Circle } from "@shopify/react-native-skia"; import { useSharedValue, withRepeat, withTiming, } from "react-native-reanimated"; export const HelloWorld = () => { const size = 256; const r = useSharedValue(0); useEffect(() => { r.value = withRepeat(withTiming(size * 0.33, { duration: 1000 }), -1); }, [r, size]); return ( <Canvas style={{ flex: 1 }}> {/* passing animated r value as prop to circle */} <Circle cx={200} cy={100} r={r} color="cyan" /> </Canvas> ); };
You can pass animated shared value as usual react state/prop.
Conclusion
React Native Skia is the best way to introduce 2D graphics in the React Native world. You can easily create basic 2D arcade games, create isomorphic UI designs, etc.
This was a teaser of React Native Skia but it has lots of rich APIs that can do amazing things like Image filtering, Adding 2D text, and rendering shaders. I will cover these topics in the upcoming series.
As we can see Skia pushes the limit
of React Native and we can create something that was beyond the limit such as creating 2D games, using shaders to render complex graphics etc.
That's it for today. If you like this blog and are curious to learn more, don't forget to check the official documentation by Shopify.
Please tap on the heart emoji if you find it useful. I will be back with another blog.
Thank you for reading this.