UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

75 lines (63 loc) 2.9 kB
'use strict'; import type { AnyRecord } from '../../../common'; import { ReanimatedError } from '../../../common'; import type { StyleBuilder } from '../../../common/style'; import type { ShadowNodeWrapper } from '../../../commonTypes'; import type { ViewInfo } from '../../../createAnimatedComponent/commonTypes'; import type { CSSStyle } from '../../types'; import type { ICSSManager } from '../../types/interfaces'; import { filterCSSAndStyleProperties } from '../../utils'; import { setViewStyle } from '../proxy'; import { getStyleBuilder, hasStyleBuilder } from '../registry'; import CSSAnimationsManager from './CSSAnimationsManager'; import CSSTransitionsManager from './CSSTransitionsManager'; export default class CSSManager implements ICSSManager { private readonly cssAnimationsManager: CSSAnimationsManager; private readonly cssTransitionsManager: CSSTransitionsManager; private readonly viewTag: number; private readonly viewName: string; private readonly styleBuilder: StyleBuilder<AnyRecord> | null = null; private isFirstUpdate: boolean = true; constructor({ shadowNodeWrapper, viewTag, viewName = 'RCTView' }: ViewInfo) { const tag = (this.viewTag = viewTag as number); const wrapper = shadowNodeWrapper as ShadowNodeWrapper; this.viewName = viewName; this.styleBuilder = hasStyleBuilder(viewName) ? getStyleBuilder(viewName) : null; this.cssAnimationsManager = new CSSAnimationsManager( wrapper, viewName, tag ); this.cssTransitionsManager = new CSSTransitionsManager(wrapper, tag); } update(style: CSSStyle): void { const [animationProperties, transitionProperties, filteredStyle] = filterCSSAndStyleProperties(style); if (!this.styleBuilder && (animationProperties || transitionProperties)) { throw new ReanimatedError( `Tried to apply CSS animations to ${this.viewName} which is not supported` ); } const normalizedStyle = this.styleBuilder?.buildFrom(filteredStyle); // If the update is called during the first css style update, we won't // trigger CSS transitions and set styles before attaching CSS transitions if (this.isFirstUpdate && normalizedStyle) { setViewStyle(this.viewTag, normalizedStyle); } this.cssTransitionsManager.update(transitionProperties); this.cssAnimationsManager.update(animationProperties); // If the current update is not the fist one, we want to update CSS // animations and transitions first and update the style then to make // sure that the new transition is fired with new settings (like duration) if (!this.isFirstUpdate && normalizedStyle) { setViewStyle(this.viewTag, normalizedStyle); } this.isFirstUpdate = false; } unmountCleanup(): void { this.cssAnimationsManager.unmountCleanup(); this.cssTransitionsManager.unmountCleanup(); } }