Canvas & 3D Animation using rN SKIA

Vilva Athiban P B

@vilvaathibanpb

Work

Omio, Berlin

Senior Engineer

Platform team

OOO

Love to teach

Inconsistent OSS contributor

Tech Speaker

Mentor

FE, BE & Tooling

Hobbies

Travel

Hiking

Cycling

Sleeping

ABOUT ME

How many hate maths class?

RN Skia?

Skia - 2D Graphics Library

Graphic engine for multiple platforms

Custom graphics/shapes

Custom Animations

Manipulating images

CANVAS and others

Canvas

Painting

Group

Shapes

Images

Text

Shaders and Filters

Animations in RN SKIA

useValue - Skia variables 

 

useComputedValue - Computed from useValue

 

useClockValue - every Display frame

Canvas animations

Charts

export const BarChart = () => {
  // D3 data Calculations
  const path = () => {
    const newPath = Skia.Path.Make();
    data.forEach((dataPoint) => {
      const rect = Skia.XYWHRect(
        x(dataPoint.label) - GRAPH_BAR_WIDTH / 2,
        graphHeight,
        GRAPH_BAR_WIDTH,
        y(dataPoint.value) * -1
      );
      const rrect = Skia.RRectXY(rect, 8, 8);
      newPath.addRRect(rrect);
    });
    return newPath;
  }

  return (
    <Canvas style={styles.canvas}>
    	<Path path={path()} color="green" />
    </Canvas>
  );
};

Charts

export const BarChart = () => {
  // D3 data Calculations
  const animationState = useValue(0);
  
  const animate = () => {
    animationState.current = 0;
    runTiming(animationState, 1, {
      duration: 1600,
      easing: Easing.inOut(Easing.exp),
    });
  };

  const path = useComputedValue(() => {
    const newPath = Skia.Path.Make();
    data.forEach((dataPoint) => {
      const rect = Skia.XYWHRect(
        x(dataPoint.label) - GRAPH_BAR_WIDTH / 2,
        graphHeight,
        GRAPH_BAR_WIDTH,
        y(dataPoint.value * animationState.current) * -1
      );
      const rrect = Skia.RRectXY(rect, 8, 8);
      newPath.addRRect(rrect);
    });
    return newPath;
  }, [animationState]);

  return (
    <>
      <Canvas style={styles.canvas}>
        <Path path={path} color="green" />
      </Canvas>
      <Button title="Animate!" onPress={animate} />
    </>
  );
};

Charts

pulse


export const Pulse = () => {
  const logo = useImage(require("./react-india.jpeg"));

  return (
      <Canvas style={{ height: 600, width: 600 }}>
        <Circle cx={300} cy={300} r={100} opacity={1} color="#1C0F3F" />
        <Image
          image={logo}
          fit="contain"
          x={250}
          y={250}
          width={100}
          height={100}
        />
      </Canvas>
  );
};

export const Pulse = () => {
  const logo = useImage(require("./react-india.jpeg"));
  
  const clockValue = useClockValue();
  const scale = useComputedValue(() => {
    return getScale(clockValue.current);
  }, [clockValue]);

  const opacity = useComputedValue(() => {
    return getOpacity(clockValue.current);
  }, [clockValue]);

  const outerScale = useComputedValue(() => {
    return getScaleOuter(clockValue.current);
  }, [clockValue]);

  const outerOpacity = useComputedValue(() => {
    return getOpacityOuter(clockValue.current);
  }, [clockValue]);

  return (
      <Canvas style={{ height: 600, width: 600 }}>
        <Circle cx={300} cy={300} r={100} opacity={1} color="#1C0F3F" />
        <Circle cx={300} cy={300} r={scale} opacity={opacity} color="#1C0F3F" />
        <Circle cx={300} cy={300} r={outerScale} opacity={outerOpacity}
          color="#1C0F3F"
        />
        <Image
          image={logo}
          fit="contain"
          x={250}
          y={250}
          width={100}
          height={100}
        />
      </Canvas>
  );
};
export const ExpoLogo = () => {
  const path = Skia.Path.Make();
  path.moveTo(210, 300);
  path.lineTo(300, 150);
  path.lineTo(390, 300);

  return (
    <Canvas style={styles.animationContainer}>
       <Fill color="black" />
         <Path path={path} color="white" style="stroke" strokeWidth={50} strokeCap="round"
           start={0}
           end={1}
         />
    </Canvas>
  );
};

PATH ANIMATION

export const ExpoLogo = () => {
  const interval = 1500;

  const clock = useClockValue();
  const forwardState = useComputedValue(() => {
    if (clock.current % (interval * 2) < interval) {
      return 1;
    }
    return (clock.current % interval) / interval;
  }, [clock]);

  const rewindState = useComputedValue(() => {
    if (clock.current % (interval * 2) < interval) {
      return (clock.current % interval) / interval;
    }
    return 0;
  }, [clock]);

  return (
  // existing code
        <Path
          path={path}
          // exisiting props
          start={rewindState}
          end={forwardState}
        />
  );
};

PATH ANIMATION

PATH ANIMATION

Transitions

export const Transition = () => {
  const image2 = useImage(require("./dp.jpeg"));

  return (
    <View style={{ flex: 1 }}>
      <StatusBar />
          <Canvas 
            style={{ flex: 1 }} 
            pointerEvents={"none"} >
              <Image 
                x={0} 
                y={0} 
                width={width} 
                height={height} 
                image={image2} 
              />
          </Canvas>
    </View>
  );
};

Transitions

export const Transition = () => {
  const circle = useSharedValue({ x: 0, y: 0, r: 0 });
  const transition = useSharedValue(0);
  const tap = Gesture.Tap().onEnd(async (e) => {
    const r = Math.max(
      ...corners.map((corner) => dist(corner, { x: e.x, y: e.y }))
    );
    circle.value = { x: e.x, y: e.y, r };
    transition.value = 0;
    transition.value = withTiming(1, { duration: 2000, easing: Easing.ease });
  });

  const r = useDerivedValue(() => {
    return mix(transition.value, 0, circle.value.r);
  });

  return (
    <Canvas style={{ flex: 1 }} pointerEvents={"none"}>
      <Rect x={0} y={0} width={width} height={height} color="black" />
      <Circle c={circle} r={r}>
        <ImageShader
          image={image2}
          x={0}
          y={0}
          width={width}
          height={height}
          fit="cover"
          />
      </Circle>
    </Canvas>
  );
};

Transitions

3D in RN SKIA

Is it even possible? Recommended?

What is 3d?

CODE & DEMO TIME

THank you

vilvaathiban.com

for being a great audience. Connect with me for questions, feedback or networking

3D with RN skia

By Vilva Athiban

3D with RN skia

  • 170