UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

137 lines (127 loc) 4.46 kB
'use strict'; import { isNumber, ReanimatedError } from '../../../../common'; import type { CSSAnimationDirection, CSSAnimationFillMode, CSSAnimationIterationCount, CSSAnimationPlayState, SingleCSSAnimationSettings, } from '../../../types'; import { deepEqual } from '../../../utils'; import type { NormalizedSingleCSSAnimationSettings } from '../../types'; import { normalizeDelay, normalizeDuration, normalizeTimingFunction, } from '../common'; import { VALID_ANIMATION_DIRECTIONS, VALID_FILL_MODES, VALID_PLAY_STATES, } from './constants'; export const ERROR_MESSAGES = { invalidAnimationDirection: (direction: CSSAnimationDirection) => `Invalid animation direction "${direction}".`, invalidIterationCount: (iterationCount: CSSAnimationIterationCount) => `Invalid iteration count "${iterationCount}". Expected a number or "infinite".`, negativeIterationCount: (iterationCount: number) => `Iteration count cannot be negative, received "${iterationCount}".`, invalidFillMode: (fillMode: CSSAnimationFillMode) => `Invalid fill mode "${fillMode}".`, invalidPlayState: (playState: CSSAnimationPlayState) => `Invalid play state "${playState}".`, }; export function normalizeDirection( direction: CSSAnimationDirection = 'normal' ): CSSAnimationDirection { if (!VALID_ANIMATION_DIRECTIONS.has(direction)) { throw new ReanimatedError( ERROR_MESSAGES.invalidAnimationDirection(direction) ); } return direction; } export function normalizeIterationCount( iterationCount: CSSAnimationIterationCount = 1 ): number { if (iterationCount === 'infinite' || iterationCount === Infinity) { return -1; } else if (!isNumber(iterationCount)) { throw new ReanimatedError( ERROR_MESSAGES.invalidIterationCount(iterationCount) ); } else if (iterationCount < 0) { throw new ReanimatedError( ERROR_MESSAGES.negativeIterationCount(iterationCount) ); } return iterationCount; } export function normalizeFillMode( fillMode: CSSAnimationFillMode = 'none' ): CSSAnimationFillMode { if (!VALID_FILL_MODES.has(fillMode)) { throw new ReanimatedError(ERROR_MESSAGES.invalidFillMode(fillMode)); } return fillMode; } export function normalizePlayState( playState: CSSAnimationPlayState = 'running' ): CSSAnimationPlayState { if (!VALID_PLAY_STATES.has(playState)) { throw new ReanimatedError(ERROR_MESSAGES.invalidPlayState(playState)); } return playState; } export function normalizeSingleCSSAnimationSettings({ animationDuration, animationTimingFunction, animationDelay, animationIterationCount, animationDirection, animationFillMode, animationPlayState, }: SingleCSSAnimationSettings): NormalizedSingleCSSAnimationSettings { return { duration: normalizeDuration(animationDuration), timingFunction: normalizeTimingFunction(animationTimingFunction), delay: normalizeDelay(animationDelay), iterationCount: normalizeIterationCount(animationIterationCount), direction: normalizeDirection(animationDirection), fillMode: normalizeFillMode(animationFillMode), playState: normalizePlayState(animationPlayState), }; } export function getAnimationSettingsUpdates( oldConfig: NormalizedSingleCSSAnimationSettings, newConfig: NormalizedSingleCSSAnimationSettings ): Partial<NormalizedSingleCSSAnimationSettings> { const updatedSettings: Partial<NormalizedSingleCSSAnimationSettings> = {}; if (oldConfig.duration !== newConfig.duration) { updatedSettings.duration = newConfig.duration; } if ( oldConfig.timingFunction !== newConfig.timingFunction && (typeof oldConfig.timingFunction !== 'object' || // TODO - maybe replace by some better solution than deepEqual !deepEqual(oldConfig.timingFunction, newConfig.timingFunction)) ) { updatedSettings.timingFunction = newConfig.timingFunction; } if (oldConfig.delay !== newConfig.delay) { updatedSettings.delay = newConfig.delay; } if (oldConfig.iterationCount !== newConfig.iterationCount) { updatedSettings.iterationCount = newConfig.iterationCount; } if (oldConfig.direction !== newConfig.direction) { updatedSettings.direction = newConfig.direction; } if (oldConfig.fillMode !== newConfig.fillMode) { updatedSettings.fillMode = newConfig.fillMode; } if (oldConfig.playState !== newConfig.playState) { updatedSettings.playState = newConfig.playState; } return updatedSettings; }