Darshan Ponikar.

Introduction to React Native Skia

Cover Image for Introduction to React Native Skia
Darshan Ponikar
Darshan Ponikar

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.