@applicaster/zapp-react-native-ui-components
Version:
Applicaster Zapp React Native ui components for the Quick Brick App
123 lines (110 loc) • 3.12 kB
JavaScript
import { Animated } from "react-native";
import { NAV_ACTION_PUSH, NAV_ACTION_BACK } from "./Transitioner";
type TransitionConfig = {
duration: number;
easing: any;
from: {
style: any;
};
to: {
style: any;
};
};
type Props = {
transitionConfig: TransitionConfig;
contentStyle: { [string]: any };
};
/**
* Manages animation for the Transitioner,
* which can be applied as a parent to ANY children.
* The crucial element here is the transitionConfig object
* which must have a proper structure, see types above ^.
*/
export class AnimationManager {
constructor(props: Props) {
this.animatedValue = new Animated.Value(0.0);
this.config = props.transitionConfig(
this.animatedValue,
props?.isRTL || false
);
}
/**
* Initial state for Transitioner. This is probably redudant
* since any animation starts first with a proper setup of the state,
* but better not push our luck here.
* = = = = = = = = = = = =
* Caveat: there is only one scene in the initial state,
* rendered as the final state of imaginary animation, in "to".
* The looks/style, however, is from the initial "push.from"
*/
initialState() {
return {
animating: false,
duration: this.config.push.duration,
easing: this.config.push.easing,
from: {
index: 0,
},
to: {
index: 0,
...this.config.push.from, // special case: we have a single scene on app start
},
};
}
/**
* Resets the animatedValue to 0.0 and returns a state object with:
* - to|from indexes (which scenes to animate)
* - style of to|from animations
* Currently only "push" and "back" animations are supported
*
* @param {object} to contains style to animate and scenes index
* @param {string} action push|back
* @param {number} stepsBack number of steps back
*/
stateForAction({ to, scenes }, action, stepsBack) {
let rootIndex = to.index;
switch (action) {
case NAV_ACTION_PUSH:
this.animatedValue.setValue(0.0);
return {
animating: true,
duration: this.config.push.duration,
easing: this.config.push.easing,
from: {
index: rootIndex,
...this.config.push.from,
},
to: {
index: rootIndex + 1,
...this.config.push.to,
},
};
case NAV_ACTION_BACK:
this.animatedValue.setValue(0.0);
rootIndex = scenes.length > 1 ? to.index : 1;
return {
animating: true,
duration: this.config.back.duration,
easing: this.config.back.easing,
from: {
index: rootIndex,
...this.config.back.from,
},
to: {
index: rootIndex - stepsBack,
...this.config.back.to,
},
};
}
}
animate(state, callback) {
Animated.timing(this.animatedValue, {
toValue: 1.0,
duration: state.duration,
easing: state.easing,
useNativeDriver: true,
}).start(() => {
callback();
});
}
}