UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

84 lines (73 loc) 2.6 kB
'use strict'; import type { NativeSyntheticEvent } from 'react-native'; import { registerEventHandler, unregisterEventHandler } from './core'; import type { EventPayload, ReanimatedEvent } from './hook/commonTypes'; import { shouldBeUseWeb } from './PlatformChecker'; const SHOULD_BE_USE_WEB = shouldBeUseWeb(); type JSEvent<Event extends object> = NativeSyntheticEvent<EventPayload<Event>>; // In JS implementation (e.g. for web) we don't use Reanimated's // event emitter, therefore we have to handle here // the event that came from React Native and convert it. function jsListener<Event extends object>( eventName: string, handler: (event: ReanimatedEvent<Event>) => void ) { return (evt: JSEvent<Event>) => { handler({ ...evt.nativeEvent, eventName } as ReanimatedEvent<Event>); }; } export default class WorkletEventHandler<Event extends object> { worklet: (event: ReanimatedEvent<Event>) => void; eventNames: string[]; reattachNeeded: boolean; listeners: | Record<string, (event: ReanimatedEvent<ReanimatedEvent<Event>>) => void> | Record<string, (event: JSEvent<Event>) => void>; viewTag: number | undefined; registrations: number[]; constructor( worklet: (event: ReanimatedEvent<Event>) => void, eventNames: string[] = [] ) { this.worklet = worklet; this.eventNames = eventNames; this.reattachNeeded = false; this.listeners = {}; this.viewTag = undefined; this.registrations = []; if (SHOULD_BE_USE_WEB) { this.listeners = eventNames.reduce( ( acc: Record<string, (event: JSEvent<Event>) => void>, eventName: string ) => { acc[eventName] = jsListener(eventName, worklet); return acc; }, {} ); } } updateWorklet(newWorklet: (event: ReanimatedEvent<Event>) => void): void { this.worklet = newWorklet; this.reattachNeeded = true; } registerForEvents(viewTag: number, fallbackEventName?: string): void { this.viewTag = viewTag; this.registrations = this.eventNames.map((eventName) => registerEventHandler(this.worklet, eventName, viewTag) ); if (this.registrations.length === 0 && fallbackEventName) { this.registrations.push( registerEventHandler(this.worklet, fallbackEventName, viewTag) ); } } registerForEventByName(eventName: string) { this.registrations.push(registerEventHandler(this.worklet, eventName)); } unregisterFromEvents(): void { this.registrations.forEach((id) => unregisterEventHandler(id)); this.registrations = []; } }