Closed sbycrosz closed 3 years ago
Yes, it's because d3 is being run on JS Thread.
Right now there is no way to run external functions on UI Thread.
cc @kmagiera @Szymon20000
We're aware of this issue but for now, it's not possible to run an arbitrary function on the JS thread.
But it is possible to convert that to worklet. But yeah, it's hard.
@terrysahaidak Is it possible to easily convert my own pure function to worklet, that for example looks like that:
fn = (x, y) => x * y
Or should I have to entirely rewrite this function as a worklet?
(in my case I have a much bigger function that calculates props for <Line />
basing on x, y and length, but it is still a function without any side-effects)
Whats the correct way to morph from one SVG Path to another ? Do we need to use the d3-interpolate-path library or its possible to do it with the tools provided with reanimated its self ?
Hi @haibert, I managed to add reanimated support to d3-interpolate-path, which you can check out here
Alternatively, on your package.json
"d3-interpolate-path": "https://github.com/sbycrosz/d3-interpolate-path.git#feat/react-native-reanimated-support",
That is amazing. Im sorry but Im confused as to how we would actually implement the worklets? Using the code in this issue as an example makes my app crash, i'm assuming this is because the interpolation is not happening on the UI thread? Do we have to run the interpolation on the UI thread by using runOnUI? This is how the code looks right now.
import React, { useState } from 'react'
import { View } from 'react-native'
import Animated, {
useSharedValue,
useAnimatedProps,
withTiming,
Easing,
runOnUI,
} from 'react-native-reanimated'
import Svg, { Path } from 'react-native-svg'
//d3-interpolator
import { interpolatePath } from 'd3-interpolate-path'
const AnimatedPath = Animated.createAnimatedComponent(Path)
Animated.addWhitelistedNativeProps({
stroke: true,
})
const PATH1 = 'M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2V9z'
const PATH2 =
'M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.501 5.501 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z'
const HomeSVG = ({ color, size }) => {
const progress = useSharedValue(0)
const interpolator = interpolatePath(PATH1, PATH2)
const animatedProps = useAnimatedProps(() => {
const path = runOnUI(interpolator)(progress.value)
return { d: path }
})
return (
<View
onTouchStart={() => {
progress.value = withTiming(progress.value ? 0 : 1, {
duration: 1000,
easing: Easing.inOut(Easing.cubic),
})
}}
>
<Svg width={size} height={size} viewBox="0 0 24 24">
<AnimatedPath
stroke={color}
strokeWidth={2}
fill="none"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"
animatedProps={animatedProps}
/>
</Svg>
</View>
)
}
export default HomeSVG
Hi, you can check out my WIP branch. I haven't worked on it for a while but hopefully, it still works.
Hello, I just realized I was not installing your branch. After I install your branch and run I get the following error message
While trying to resolve module `d3-interpolate-path` from file `/Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/src/components/animatedNavBarTest/HomeSVG.js`, the package `/Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/build/d3-interpolate-path.js`. Indeed, none of these files exist:
* /Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/build/d3-interpolate-path.js(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json)
* /Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/build/d3-interpolate-path.js/index(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json)
InternalError Metro has encountered an error: While trying to resolve module `d3-interpolate-path` from file `/Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/src/components/animatedNavBarTest/HomeSVG.js`, the package `/Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/build/d3-interpolate-path.js`. Indeed, none of these files exist:
* /Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/build/d3-interpolate-path.js(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json)
* /Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/d3-interpolate-path/build/d3-interpolate-path.js/index(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json): /Users/hb/Desktop/EjectEventShare/1EventShare-dev-client/node_modules/metro/src/node-haste/DependencyGraph.js (376:17)
seems like theres a 'build/d3-interpolate-path.js' file missing.
It's working fine on my machine. Try deleting your node_modules and then reinstalling
hmmm, still same error. im doing yarn add sbycrosz/d3-interpolate-path, do you see the build/d3-interpolate-path.js file ? im using expo im not sure if this makes a difference
I have not tried Expo so I can't comment on that, but did you try my example repo?
Also, you need to add the specific branch of my fork.
AFAIK yarn add sbycrosz/d3-interpolate-path
will try to pull master by default
Description
Hi, I wanted to use d3-interpolate-path with reanimated-v2 to make animated charts
At the moment, I'm kind of stuck when calling the interpolate function from useAnimatedProps, which I suspect is because d3-interpolate-path is being run on RN thread instead of the UI thread. Is this correct? Is there a way to have external functions run on UI thread instead?
Thanks!
Code
https://github.com/sbycrosz/reanimated-2-playground/blob/master/Screen.js#L27
Package versions