UNPKG

react-native-filament

Version:

A real-time physically based 3D rendering engine for React Native

50 lines (43 loc) 1.91 kB
import { type SharedValue as ReanimatedSharedValue } from 'react-native-reanimated' import { useSharedValue, type ISharedValue as WorkletsCoreSharedValue } from 'react-native-worklets-core' import { useFilamentContext } from './useFilamentContext' import { useEffect } from 'react' import { ReanimatedProxy } from '../dependencies/ReanimatedProxy' /** * react-native-filament uses react-native-worklets-core for creating shared values, which works very similar to * react-native-reanimated's shared values. However, you can't pass a reanimated shared value to a worklets core shared value directly. * This hook allows you to sync a reanimated shared value with a worklets core shared value. * * @example * ```tsx * const reanimatedSharedValue = useSharedValue(0) * const workletsCoreSharedValue = useSyncSharedValue(reanimatedSharedValue) * * // animate reanimatedSharedValue * * return <ModelInstance index={0} rotate={workletsCoreSharedValue} /> * ``` */ export function useSyncSharedValue<T>(reanimatedSharedValue: ReanimatedSharedValue<T>): WorkletsCoreSharedValue<T> { const workletsCoreSharedValue = useSharedValue(reanimatedSharedValue.value) const { workletContext } = useFilamentContext() // Attach a listener to the reanimated value that runs on the UI thread and updates the worklets core shared value useEffect(() => { const id = Math.floor(Math.random() * 1000000) const callback = workletContext.createRunAsync((value: T) => { 'worklet' workletsCoreSharedValue.value = value }) ReanimatedProxy.runOnUI(() => { 'worklet' reanimatedSharedValue.addListener(id, callback) })() return () => { ReanimatedProxy.runOnUI(() => { 'worklet' reanimatedSharedValue.removeListener(id) })() } }, [reanimatedSharedValue, workletContext, workletsCoreSharedValue]) return workletsCoreSharedValue }