UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

135 lines (124 loc) 4.14 kB
import { useEffect, useRef } from 'react'; import { makeRemote } from '../core'; import { isWeb, isJest } from '../PlatformChecker'; import WorkletEventHandler from '../WorkletEventHandler'; // TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. export const useEvent = function (handler) { let eventNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; let rebuild = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; const initRef = useRef(null); if (initRef.current === null) { initRef.current = new WorkletEventHandler(handler, eventNames); } else if (rebuild) { initRef.current.updateWorklet(handler); } return initRef; // TODO TYPESCRIPT This cast is to get rid of .d.ts file. }; // TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. export const useHandler = function (handlers, dependencies) { const initRef = useRef(null); if (initRef.current === null) { initRef.current = { context: makeRemote({}), savedDependencies: [] }; } useEffect(() => { return () => { initRef.current = null; }; }, []); const { context, savedDependencies } = initRef.current; dependencies = buildDependencies(dependencies, handlers); const doDependenciesDiffer = !areDependenciesEqual(dependencies, savedDependencies); initRef.current.savedDependencies = dependencies; const useWeb = isWeb() || isJest(); return { context, doDependenciesDiffer, useWeb }; // TODO TYPESCRIPT This temporary cast is to get rid of .d.ts file. }; // builds one big hash from multiple worklets' hashes export function buildWorkletsHash(handlers) { return Object.values(handlers).reduce((acc, worklet) => // eslint-disable-next-line @typescript-eslint/no-non-null-assertion acc + worklet.__workletHash.toString(), ''); } // builds dependencies array for gesture handlers function buildDependencies(dependencies, handlers) { const handlersList = Object.values(handlers).filter(handler => handler !== undefined); if (!dependencies) { dependencies = handlersList.map(handler => { return { workletHash: handler.__workletHash, closure: handler._closure }; }); } else { dependencies.push(buildWorkletsHash(handlersList)); } return dependencies; } // this is supposed to work as useEffect comparison function areDependenciesEqual(nextDeps, prevDeps) { function is(x, y) { /* eslint-disable no-self-compare */ return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y; /* eslint-enable no-self-compare */ } const objectIs = typeof Object.is === 'function' ? Object.is : is; function areHookInputsEqual(nextDeps, prevDeps) { if (!nextDeps || !prevDeps || prevDeps.length !== nextDeps.length) { return false; } for (let i = 0; i < prevDeps.length; ++i) { if (!objectIs(nextDeps[i], prevDeps[i])) { return false; } } return true; } return areHookInputsEqual(nextDeps, prevDeps); } export function isAnimated(prop) { 'worklet'; if (Array.isArray(prop)) { return prop.some(isAnimated); } else if (typeof prop === 'object' && prop !== null) { if (prop.onFrame !== undefined) { return true; } else { return Object.values(prop).some(isAnimated); } } return false; } export function shallowEqual(a, b) { 'worklet'; const aKeys = Object.keys(a); const bKeys = Object.keys(b); if (aKeys.length !== bKeys.length) { return false; } for (let i = 0; i < aKeys.length; i++) { if (a[aKeys[i]] !== b[aKeys[i]]) { return false; } } return true; } export const validateAnimatedStyles = styles => { 'worklet'; if (typeof styles !== 'object') { throw new Error(`useAnimatedStyle has to return an object, found ${typeof styles} instead`); } else if (Array.isArray(styles)) { throw new Error('useAnimatedStyle has to return an object and cannot return static styles combined with dynamic ones. Please do merging where a component receives props.'); } }; //# sourceMappingURL=utils.js.map