import type Animated from "react-native-reanimated" ; declare let _WORKLET ; export interface AnimationState { current : number ; } export interface PhysicsAnimationState extends AnimationState { velocity : number ; } export type Animation < State extends AnimationState = AnimationState , PrevState = State > = { onFrame : ( animation : State , now : number ) => boolean ; onStart : ( animation : State , value : number , now : number , lastAnimation : PrevState ) => void ; callback ? : ( ) => void ; } & State ; export type AnimationParameter < State extends AnimationState = AnimationState > = Animation < State > | ( ( ) => Animation < State > ) | number ; summary export const animationParameter = < State extends AnimationState = AnimationState > ( animationParam ) => { "worklet" ; if ( typeof animationParam === "number" ) { throw new Error ( "Expected Animation as parameter" ) ; } return typeof animationParam === "function" ? animationParam ( ) : animationParam ; } ; summary example worklet export const defineAnimation = < S extends AnimationState = AnimationState , Prev extends AnimationState = AnimationState > ( factory ) => { "worklet" ; if ( _WORKLET ) { return ( factory ( ) as unknown ) as number ; } return ( factory as unknown ) as number ; } ; interface PausableAnimation extends AnimationState { lastTimestamp : number ; elapsed : number ; } summary example worklet export const withPause = ( animationParam , paused ) => { "worklet" ; return defineAnimation < PausableAnimation > ( ( ) => { "worklet" ; const nextAnimation = animationParameter ( animationParam ) ; const onFrame = ( state , now ) => { const { lastTimestamp , elapsed } = state ; if ( paused . value ) { state . elapsed = now - lastTimestamp ; return false ; } const dt = now - elapsed ; const finished = nextAnimation . onFrame ( nextAnimation , dt ) ; state . current = nextAnimation . current ; state . lastTimestamp = dt ; return finished ; } ; const onStart = ( state , value , now , previousState ) => { state . lastTimestamp = now ; state . elapsed = 0 ; nextAnimation . onStart ( nextAnimation , value , now , previousState ) ; } ; return { onFrame , onStart , callback : nextAnimation . callback , } ; } ) ; } ; summary example worklet export const withBouncing = ( animationParam , lowerBound , upperBound ) : number => { "worklet" ; return defineAnimation < PhysicsAnimationState , PhysicsAnimationState > ( ( ) => { "worklet" ; const nextAnimation = animationParameter ( animationParam ) ; const onFrame = ( state , now ) => { const finished = nextAnimation . onFrame ( nextAnimation , now ) ; const { velocity , current } = nextAnimation ; state . current = current ; if ( ( velocity < 0 && state . current <= lowerBound ) || ( velocity > 0 && state . current >= upperBound ) ) { state . current = velocity < 0 ? lowerBound : upperBound ; nextAnimation . velocity *= - 0.5 ; } return finished ; } ; const onStart = ( _state , value , now , previousState ) => { nextAnimation . onStart ( nextAnimation , value , now , previousState ) ; } ; return { onFrame , onStart , callback : nextAnimation . callback , } ; } ) ; } ;