links: React Native MOC


Introduction

import React from "react";
import { Canvas, Skia, Shader, Fill } from "@shopify/react-native-skia";
 
const source = Skia.RuntimeEffect.Make(`
uniform float4 colors[4];
vec4 main(vec2 xy) {
  return colors[1];
}`)!;
 
const colors = ["#dafb61", "#61DAFB", "#fb61da", "#61fbcf"].map((c) =>
  Skia.Color(c)
);
 
export const SDF = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <Fill>
        <Shader source={source} uniforms={{ colors }} />
      </Fill>
    </Canvas>
  );
};

Let’s consider this starter template to learn about shaders in skia using react native

The Shader component takes two props:

  1. source which is skia shader language
  2. uniforms which are like gateway/input that you would like to pass from React Native to Shader.

Here we are passing colors from React Native and accessing the source by using a uniform like this uniform float4 colors[4];

Any Skia Shader will have a main method which returns a vec4 object (color) and takes vec2 xy the position of the point in the canvas.

Draw a Circle

If you want to draw a circle on the Canvas via Shader you can utilize the signed distance function Logic.

What is the Signed Distance Function??

It’s a method which takes a position as input and calculates whether it is inside or outside the shape. If the value is < 0 the point is inside the shape else outside the shape

Now if I want to draw a circle of radius 50

float sdCircle(vec2 pos, float radius) {
  return length(pos) - radius;
}
 
float d = sdCircle(xy, 50)

The d can be negative, 0 or positive let’s go through each case

  1. The length of the position is 15 then 15 - 50 = -35 which means the point is inside the circle
  2. The length of the position is 50 then 50 - 50 = 0 which means the point is on the circle
  3. The length of the position is 65 then 65 - 50 = 15 which means the point is outside the circle

Translate the position of the Circle

When you draw a circle, It tries to draw from top left as it’s considered as (0, 0) the starting point. What if you want to draw the circle at the center.

float2 translate(float2 pos, float2 offset) {
  return pos - offset;
}

tags: react-native skia sources: