UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

129 lines (116 loc) 3.54 kB
import { defineAnimation } from './util'; import { Animation, AnimationCallback, NextAnimation, AnimatableValue, Timestamp, HigherOrderAnimation, } from './commonTypes'; export interface RepeatAnimation extends Animation<RepeatAnimation>, HigherOrderAnimation { reps: number; startValue: AnimatableValue; toValue?: AnimatableValue; previousAnimation?: RepeatAnimation; } export interface InnerRepeatAnimation extends Omit<RepeatAnimation, 'toValue' | 'startValue'> { toValue: number; startValue: number; } export function withRepeat( _nextAnimation: NextAnimation<RepeatAnimation>, numberOfReps = 2, reverse = false, callback?: AnimationCallback ): Animation<RepeatAnimation> { 'worklet'; return defineAnimation<RepeatAnimation>(_nextAnimation, () => { 'worklet'; const nextAnimation: RepeatAnimation = typeof _nextAnimation === 'function' ? _nextAnimation() : _nextAnimation; function repeat(animation: InnerRepeatAnimation, now: Timestamp): boolean { const finished = nextAnimation.onFrame(nextAnimation, now); animation.current = nextAnimation.current; if (finished) { animation.reps += 1; // call inner animation's callback on every repetition // as the second argument the animation's current value is passed if (nextAnimation.callback) { nextAnimation.callback(true /* finished */, animation.current); } if (numberOfReps > 0 && animation.reps >= numberOfReps) { return true; } const startValue = reverse ? (nextAnimation.current as number) : animation.startValue; if (reverse) { nextAnimation.toValue = animation.startValue; animation.startValue = startValue; } nextAnimation.onStart( nextAnimation, startValue, now, nextAnimation.previousAnimation as RepeatAnimation ); return false; } return false; } const repCallback = (finished: boolean): void => { if (callback) { callback(finished); } // when cancelled call inner animation's callback if (!finished && nextAnimation.callback) { nextAnimation.callback(false /* finished */); } }; function onStart( animation: RepeatAnimation, value: AnimatableValue, now: Timestamp, previousAnimation: RepeatAnimation ): void { animation.startValue = value; animation.reps = 0; nextAnimation.onStart(nextAnimation, value, now, previousAnimation); } return { isHigherOrder: true, onFrame: repeat, onStart, reps: 0, current: nextAnimation.current, callback: repCallback, startValue: 0, } as RepeatAnimation; }); } /** * @deprecated Kept for backward compatibility. Will be removed soon. */ export function repeat( _nextAnimation: NextAnimation<RepeatAnimation>, numberOfReps = 2, reverse = false, callback?: AnimationCallback ): Animation<RepeatAnimation> { 'worklet'; console.warn( 'Method `repeat` is deprecated. Please use `withRepeat` instead' ); return withRepeat(_nextAnimation, numberOfReps, reverse, callback); } export function loop( nextAnimation: NextAnimation<RepeatAnimation>, numberOfLoops = 1 ): Animation<RepeatAnimation> { 'worklet'; console.warn('Method `loop` is deprecated. Please use `withRepeat` instead'); return repeat(nextAnimation, Math.round(numberOfLoops * 2), true); }