UNPKG

@td-design/react-native

Version:

react-native UI组件库

182 lines (181 loc) 4.02 kB
import React, { PureComponent } from 'react'; import { Animated, Easing } from 'react-native'; export default class Indicator extends PureComponent { static displayName = 'Indicator'; static defaultProps = { animationEasing: Easing.linear, animationDuration: 1200, hideAnimationDuration: 200, animating: true, interaction: true, hidesWhenStopped: true, count: 1 }; constructor(props) { super(props); /* * 0 -> 1 * | startAnimation * | resumeAnimation * * 1 -> -1 * | stopAnimation * * -1 -> 0 * | saveAnimation */ this.animationState = 0; this.savedValue = 0; const { animating } = this.props; this.state = { progress: new Animated.Value(0), hideAnimation: new Animated.Value(animating ? 1 : 0) }; } componentDidMount() { const { animating } = this.props; if (animating) { this.startAnimation(); } } componentDidUpdate(prevProps) { const { animating } = this.props; if (animating && !prevProps.animating) { this.resumeAnimation(); } if (!animating && prevProps.animating) { this.stopAnimation(); } if (animating !== prevProps.animating) { const { hideAnimation } = this.state; const { hideAnimationDuration: duration } = this.props; Animated.timing(hideAnimation, { toValue: animating ? 1 : 0, duration, useNativeDriver: true }).start(); } } startAnimation() { const { progress } = this.state; const { interaction, animationEasing, animationDuration } = this.props; if (0 !== this.animationState) { return; } const animation = Animated.timing(progress, { duration: animationDuration, easing: animationEasing, useNativeDriver: true, isInteraction: interaction, toValue: 1 }); Animated.loop(animation).start(); this.animationState = 1; } stopAnimation() { const { progress } = this.state; if (1 !== this.animationState) { return; } const listener = progress.addListener(_ref => { let { value } = _ref; progress.removeListener(listener); progress.stopAnimation(() => this.saveAnimation(value)); }); this.animationState = -1; } saveAnimation(value) { const { animating } = this.props; this.savedValue = value; this.animationState = 0; if (animating) { this.resumeAnimation(); } } resumeAnimation() { const { progress } = this.state; const { interaction, animationDuration } = this.props; if (0 !== this.animationState) { return; } Animated.timing(progress, { useNativeDriver: true, isInteraction: interaction, duration: (1 - this.savedValue) * animationDuration, toValue: 1 }).start(_ref2 => { let { finished } = _ref2; if (finished) { progress.setValue(0); this.animationState = 0; this.startAnimation(); } }); this.savedValue = 0; this.animationState = 1; } renderComponent(_, index) { const { progress } = this.state; const { renderComponent, count } = this.props; if ('function' === typeof renderComponent) { return renderComponent({ index, count, progress }); } return null; } render() { const { hideAnimation } = this.state; const { count, hidesWhenStopped, ...props } = this.props; const styles = props.style ? [props.style] : []; if (hidesWhenStopped) { styles.push({ opacity: hideAnimation }); } return /*#__PURE__*/React.createElement(Animated.View, props, Array.from(new Array(count), this.renderComponent, this)); } } //# sourceMappingURL=Indicator.js.map