Shopify / react-native-skia

High-performance React Native Graphics using Skia
https://shopify.github.io/react-native-skia
MIT License
6.98k stars 452 forks source link

Unable to replicate an old example with useDerivedValue() instead of useComputerValue() #2614

Open uxfuture opened 2 months ago

uxfuture commented 2 months ago

Description

My expo project returns "leftPath is not a function (It is Object)" error when i replicated season5/src/Headspace/Play.tsx

Version

1.2.3

Steps to reproduce

import React from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import Slider from '@react-native-community/slider';
import type { SkPath } from '@shopify/react-native-skia';
import { Canvas, Path, Skia } from '@shopify/react-native-skia';
import { useDerivedValue, useSharedValue } from 'react-native-reanimated';
import { interpolate } from 'flubber';
const { width } = Dimensions.get("window");

const Flubber2SkiaInterpolator = (from: SkPath, to: SkPath) => {
  const interpolator = interpolate(from.toSVGString(), to.toSVGString());
  const d = 1e-3;
  const i0 = Skia.Path.MakeFromSVGString(interpolator(d))!;
  const i1 = Skia.Path.MakeFromSVGString(interpolator(1 - d))!;
  return (t: number) => {
    if (t < d) {
      return from;
    }
    if (1 - t < d) {
      return to;
    }
    return i1.interpolate(i0, t)!;
  };
};

const playLeft = Skia.Path.MakeFromSVGString(
  "M51 23V33.3V43.6V64.1V84.7V105.2L73.3 89.9L95.5 74.5C97.2 73.3 98.6 71.8 99.6 70C100.5 68.2 101 66.2 101 64.1C101 62.1 100.5 60 99.6 58.2C98.6 56.4 97.2 54.9 95.5 53.7L73.3 38.4L51 23Z"
)!;
const pauseLeft = Skia.Path.MakeFromSVGString(
  "M84.7 1C80.2 1 76 2.8 72.9 5.9C69.8 9 68 13.2 68 17.7V106.6C68 111 69.8 115.2 72.9 118.3C76 121.5 80.2 123.2 84.7 123.2C89.1 123.2 93.3 121.5 96.5 118.3C99.6 115.2 101.3 111 101.3 106.6V17.7C101.3 13.2 99.6 9 96.5 5.9C93.3 2.8 89.1 1 84.7 1Z"
)!;

const leftPath = Flubber2SkiaInterpolator(playLeft, pauseLeft);

const PathInterpolated = () => {
  const sliderSharedValue = useSharedValue(0);

  const path = useDerivedValue(() => leftPath(sliderSharedValue.value));

  return (
    <SafeAreaView style={styles.container}>
      <Canvas style={styles.canvas}>
        <Path
          path={path}
          color="white"
          style="stroke"
          strokeWidth={4}
        />
      </Canvas>
      <View style={styles.content}>
        <Slider
          style={styles.slider}
          minimumValue={0}
          maximumValue={1}
          value={sliderSharedValue.value}
          onValueChange={(value) => {
            sliderSharedValue.value = value
          }}
          minimumTrackTintColor='grey'
          maximumTrackTintColor='grey'
          thumbTintColor='white'
        />
      </View>
    </SafeAreaView>
  );
};

export default PathInterpolated;

In season5/src/Headspace/Play.tsx, useComputeValue is being used which is now preceded by useDerivedValue.

But using the above code on my expo managed project returns "leftPath is not a function (It is Object)" error after the first call (which returns from);

Tried to reproduce this in a bare react-native by prebuilding, but was lacking knowledge on worklets for getting it to work.

Snack, code example, screenshot, or link to a repository

Image

mrEuler commented 2 months ago

leftPath isn't a worklet function here. please check docs: https://docs.swmansion.com/react-native-reanimated/docs/guides/worklets