1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| import * as React from 'react' import { View, Image, StyleSheet } from 'react-native' import * as Animatable from 'react-native-animatable'
const styles = StyleSheet.create({ image: { position: 'absolute', top: 0, left: 0, zIndex: 1, }, animateImage: { position: 'absolute', top: 0, left: 0, zIndex: 2, }, })
interface Props { containerStyle: Object imageStyle: Object sources: any[] animDuration: number holdDuration: number }
interface State { current: number paused: boolean }
export default class extends React.Component<Props, State> { state = { current: 0, paused: false, }
animateImage: any timer: any
componentDidMount() { this.startAnimation() }
getNextIndex = () => { const { sources } = this.props const { current } = this.state return current === sources.length - 1 ? 0 : current + 1 }
componentWillUnmount() { this.timer && clearTimeout(this.timer) this.animateImage && this.animateImage.stopAnimation() this.animateImage = null }
startAnimation = () => { const { animDuration } = this.props if (this.animateImage) { this.animateImage.transitionTo({ opacity: 0, }, animDuration, 'ease-out') this.timer && clearTimeout(this.timer) this.timer = setTimeout(this.onAnimateEnd, animDuration) } }
onAnimateEnd = () => { const { holdDuration } = this.props this.setState({ paused: true }, () => { if (this.animateImage) { this.animateImage.transitionTo({ opacity: 1 }) this.timer && clearTimeout(this.timer) this.timer = setTimeout(() => { this.setState({ paused: false, current: this.getNextIndex() }) this.startAnimation() }, holdDuration) } }) }
render() { const { containerStyle, imageStyle, sources } = this.props if (!sources || !sources.length) { return null }
if (sources.length === 1) { return <View style={containerStyle}> <Image source={sources[0]} style={[styles.image, imageStyle]} /> </View> }
const { current, paused } = this.state const next = this.getNextIndex()
return <View style={containerStyle}> <Animatable.Image ref={ref => this.animateImage = ref} style={[styles.animateImage, imageStyle]} useNativeDriver={true} source={sources[paused ? next : current]} /> <Image source={sources[next]} style={[styles.image, imageStyle]} /> </View> } }
|