UNPKG

6.27 kBPlain TextView Raw
1'use strict';
2import NativeReanimatedModule from './NativeReanimated';
3import { isWeb, shouldBeUseWeb, isFabric } from './PlatformChecker';
4import type {
5 AnimatedKeyboardOptions,
6 SensorConfig,
7 SensorType,
8 SharedValue,
9 Value3D,
10 ValueRotation,
11} from './commonTypes';
12import { makeShareableCloneRecursive } from './shareables';
13import { initializeUIRuntime } from './initializers';
14import type { LayoutAnimationBatchItem } from './layoutReanimation/animationBuilder/commonTypes';
15import { SensorContainer } from './SensorContainer';
16
17export { startMapper, stopMapper } from './mappers';
18export { runOnJS, runOnUI, executeOnUIRuntimeSync } from './threads';
19export { createWorkletRuntime, runOnRuntime } from './runtimes';
20export type { WorkletRuntime } from './runtimes';
21export { makeShareable, makeShareableCloneRecursive } from './shareables';
22export { makeMutable } from './mutables';
23
24const SHOULD_BE_USE_WEB = shouldBeUseWeb();
25
26/**
27 * @returns `true` in Reanimated 3, doesn't exist in Reanimated 2 or 1
28 */
29export const isReanimated3 = () => true;
30
31// Superseded by check in `/src/threads.ts`.
32// Used by `react-navigation` to detect if using Reanimated 2 or 3.
33/**
34 * @deprecated This function was superseded by other checks.
35 * We keep it here for backward compatibility reasons.
36 * If you need to check if you are using Reanimated 3 or Reanimated 2
37 * please use `isReanimated3` function instead.
38 * @returns `true` in Reanimated 3, doesn't exist in Reanimated 2
39 */
40export const isConfigured = isReanimated3;
41
42// this is for web implementation
43if (SHOULD_BE_USE_WEB) {
44 global._WORKLET = false;
45 global._log = console.log;
46 global._getAnimationTimestamp = () => performance.now();
47}
48
49export function getViewProp<T>(
50 viewTag: number,
51 propName: string,
52 component?: React.Component // required on Fabric
53): Promise<T> {
54 if (isFabric() && !component) {
55 throw new Error(
56 '[Reanimated] Function `getViewProp` requires a component to be passed as an argument on Fabric.'
57 );
58 }
59
60 // eslint-disable-next-line @typescript-eslint/no-misused-promises
61 return new Promise((resolve, reject) => {
62 return NativeReanimatedModule.getViewProp(
63 viewTag,
64 propName,
65 component,
66 (result: T) => {
67 if (typeof result === 'string' && result.substr(0, 6) === 'error:') {
68 reject(result);
69 } else {
70 resolve(result);
71 }
72 }
73 );
74 });
75}
76
77function getSensorContainer(): SensorContainer {
78 if (!global.__sensorContainer) {
79 global.__sensorContainer = new SensorContainer();
80 }
81 return global.__sensorContainer;
82}
83
84export function registerEventHandler<T>(
85 eventHandler: (event: T) => void,
86 eventName: string,
87 emitterReactTag = -1
88): number {
89 function handleAndFlushAnimationFrame(eventTimestamp: number, event: T) {
90 'worklet';
91 global.__frameTimestamp = eventTimestamp;
92 eventHandler(event);
93 global.__flushAnimationFrame(eventTimestamp);
94 global.__frameTimestamp = undefined;
95 }
96 return NativeReanimatedModule.registerEventHandler(
97 makeShareableCloneRecursive(handleAndFlushAnimationFrame),
98 eventName,
99 emitterReactTag
100 );
101}
102
103export function unregisterEventHandler(id: number): void {
104 return NativeReanimatedModule.unregisterEventHandler(id);
105}
106
107export function subscribeForKeyboardEvents(
108 eventHandler: (state: number, height: number) => void,
109 options: AnimatedKeyboardOptions
110): number {
111 // TODO: this should really go with the same code path as other events, that is
112 // via registerEventHandler. For now we are copying the code from there.
113 function handleAndFlushAnimationFrame(state: number, height: number) {
114 'worklet';
115 const now = global._getAnimationTimestamp();
116 global.__frameTimestamp = now;
117 eventHandler(state, height);
118 global.__flushAnimationFrame(now);
119 global.__frameTimestamp = undefined;
120 }
121 return NativeReanimatedModule.subscribeForKeyboardEvents(
122 makeShareableCloneRecursive(handleAndFlushAnimationFrame),
123 options.isStatusBarTranslucentAndroid ?? false
124 );
125}
126
127export function unsubscribeFromKeyboardEvents(listenerId: number): void {
128 return NativeReanimatedModule.unsubscribeFromKeyboardEvents(listenerId);
129}
130
131export function registerSensor(
132 sensorType: SensorType,
133 config: SensorConfig,
134 eventHandler: (
135 data: Value3D | ValueRotation,
136 orientationDegrees: number
137 ) => void
138): number {
139 const sensorContainer = getSensorContainer();
140 return sensorContainer.registerSensor(
141 sensorType,
142 config,
143 makeShareableCloneRecursive(eventHandler)
144 );
145}
146
147export function initializeSensor(
148 sensorType: SensorType,
149 config: SensorConfig
150): SharedValue<Value3D | ValueRotation> {
151 const sensorContainer = getSensorContainer();
152 return sensorContainer.initializeSensor(sensorType, config);
153}
154
155export function unregisterSensor(sensorId: number): void {
156 const sensorContainer = getSensorContainer();
157 return sensorContainer.unregisterSensor(sensorId);
158}
159
160if (!isWeb()) {
161 initializeUIRuntime();
162}
163
164type FeaturesConfig = {
165 enableLayoutAnimations: boolean;
166 setByUser: boolean;
167};
168
169let featuresConfig: FeaturesConfig = {
170 enableLayoutAnimations: false,
171 setByUser: false,
172};
173
174export function enableLayoutAnimations(
175 flag: boolean,
176 isCallByUser = true
177): void {
178 if (isCallByUser) {
179 featuresConfig = {
180 enableLayoutAnimations: flag,
181 setByUser: true,
182 };
183 NativeReanimatedModule.enableLayoutAnimations(flag);
184 } else if (
185 !featuresConfig.setByUser &&
186 featuresConfig.enableLayoutAnimations !== flag
187 ) {
188 featuresConfig.enableLayoutAnimations = flag;
189 NativeReanimatedModule.enableLayoutAnimations(flag);
190 }
191}
192
193export function configureLayoutAnimationBatch(
194 layoutAnimationsBatch: LayoutAnimationBatchItem[]
195): void {
196 NativeReanimatedModule.configureLayoutAnimationBatch(layoutAnimationsBatch);
197}
198
199export function setShouldAnimateExitingForTag(
200 viewTag: number | HTMLElement,
201 shouldAnimate: boolean
202) {
203 NativeReanimatedModule.setShouldAnimateExitingForTag(
204 viewTag as number,
205 shouldAnimate
206 );
207}
208
209export function jsiConfigureProps(
210 uiProps: string[],
211 nativeProps: string[]
212): void {
213 if (!SHOULD_BE_USE_WEB) {
214 NativeReanimatedModule.configureProps(uiProps, nativeProps);
215 }
216}