Используя React Native, я пытаюсь сделать анимированное слайд-шоу с 3 циклами.По какой-то причине он не работает правильно в первом цикле, но делает это потом.
Проблема в том, что во второй раз появляются драконы (первое изображение), это происходит мгновенно, потому что this.state.imageThreeOpacity
, похоже, не оживляет в первый раз.
Однако по мере продолжения видео вы увидите, что оно исправляет себя.
Вот видео моего слайд-шоу в его текущем состоянии .: https://streamable.com/tpjcz
Вотмой код компонента.Цикл анимации с рекурсивной функцией animate
:
import React, { Component } from 'react';
import {
StyleSheet,
Image,
View,
Dimensions,
Animated,
} from 'react-native';
import _ from 'underscore';
import imageCacheHoc from 'react-native-image-cache-hoc';
const CacheableImage = imageCacheHoc( Image, {
validProtocols: [ 'http', 'https', '' ]
} );
const animationDistance = 250;
export default class ImageIntro extends Component {
constructor() {
super();
this.state = {
imageOneOpacity: new Animated.Value( 1 ),
imageTwoOpacity: new Animated.Value( 1 ),
imageThreeOpacity: new Animated.Value( 1 ),
imageOneZIndex: 3,
imageTwoZIndex: 2,
imageThreeZIndex: 1,
imageOneTranslateX: new Animated.Value( -( animationDistance / 2 ) ),
imageOneTranslateY: new Animated.Value( 0 ),
imageTwoTranslateX: new Animated.Value( animationDistance / 2 ),
imageTwoTranslateY: new Animated.Value( -( animationDistance / 2 ) ),
imageThreeTranslateX: new Animated.Value( 0 ),
imageThreeTranslateY: new Animated.Value( animationDistance / 2 ),
};
}
componentDidMount() {
this.animate( true );
}
animate( firstPass ) {
let {
imageOneOpacity,
imageTwoOpacity,
imageThreeOpacity,
imageOneTranslateX,
imageOneTranslateY,
imageTwoTranslateX,
imageTwoTranslateY,
imageThreeTranslateX,
imageThreeTranslateY
} = this.state;
const duration = 2000;
const delay = 1500;
setTimeout( () => {
this.animate( false );
}, ( duration * 3 ) - ( ( duration - delay ) * 3 ) );
Animated.parallel(
[
Animated.timing(
imageOneTranslateX, {
toValue: animationDistance / 2,
useNativeDriver: true,
duration: duration,
}
),
Animated.timing(
imageOneOpacity, {
toValue: 0,
useNativeDriver: true,
delay: delay,
duration: duration - delay,
}
),
]
).start( () => {
Animated.timing(
imageOneTranslateX, {
toValue: -( animationDistance / 2 ),
useNativeDriver: true,
duration: 0,
}
).start();
} );
Animated.parallel(
[
Animated.timing(
imageTwoTranslateX, {
toValue: -( animationDistance / 2 ),
useNativeDriver: true,
duration: duration,
delay: delay,
},
),
Animated.timing(
imageTwoTranslateY, {
toValue: ( animationDistance / 2 ),
useNativeDriver: true,
duration: duration,
delay: delay,
},
),
Animated.timing(
imageTwoOpacity, {
toValue: 0,
useNativeDriver: true,
delay: delay * 2,
duration: duration - delay,
}
),
]
).start( () => {
Animated.timing(
imageTwoTranslateX, {
toValue: ( animationDistance / 2 ),
useNativeDriver: true,
duration: 0,
}
).start();
Animated.timing(
imageTwoTranslateY, {
toValue: -( animationDistance / 2 ),
useNativeDriver: true,
duration: 0,
}
).start();
this.setState( { imageThreeZIndex: 4 }, () => {
Animated.timing(
imageOneOpacity, {
toValue: 1,
useNativeDriver: true,
duration: 0,
}
).start();
Animated.timing(
imageTwoOpacity, {
toValue: 1,
useNativeDriver: true,
duration: 0,
}
).start();
} );
} );
Animated.parallel(
[
Animated.timing(
imageThreeTranslateY, {
toValue: -( animationDistance / 2 ),
useNativeDriver: true,
duration: duration,
delay: delay * 2,
}
),
Animated.timing(
imageThreeOpacity, {
toValue: 0,
useNativeDriver: true,
delay: delay * 3,
duration: duration - delay,
}
),
]
).start( () => {
Animated.timing(
imageThreeTranslateY, {
toValue: ( animationDistance / 2 ),
useNativeDriver: true,
duration: 0,
}
).start();
this.setState( { imageThreeZIndex: 1 }, () => {
Animated.timing(
imageThreeOpacity, {
toValue: 1,
useNativeDriver: true,
duration: 0
}
);
} );
} );
}
render() {
const { images } = this.props;
const outputImages = () => {
let {
imageOneOpacity,
imageTwoOpacity,
imageThreeOpacity,
imageOneZIndex,
imageTwoZIndex,
imageThreeZIndex,
imageOneTranslateX,
imageOneTranslateY,
imageTwoTranslateX,
imageTwoTranslateY,
imageThreeTranslateX,
imageThreeTranslateY
} = this.state;
const animationProps = [
[ imageOneOpacity, imageOneTranslateX, imageOneTranslateY ],
[ imageTwoOpacity, imageTwoTranslateX, imageTwoTranslateY ],
[ imageThreeOpacity, imageThreeTranslateX, imageThreeTranslateY ]
];
let output = [];
_.each( images, ( image, index ) => {
output.push(
<Animated.View key={ `intro-image-${index}` } style={ [ styles.imageWrap, {
zIndex: [ imageOneZIndex, imageTwoZIndex, imageThreeZIndex ][ index ],
opacity: animationProps[ index ][ 0 ],
transform: [
{ translateX: animationProps[ index ][ 1 ] },
{ translateY: animationProps[ index ][ 2 ] }
]
} ] }>
<CacheableImage style={ styles.image }
permanent={ true }
source={ { uri: image } }/>
</Animated.View>
)
} );
return output;
};
return (
<View style={ [ styles.container ] }>
{ outputImages() }
</View>
);
}
}
const { width, height } = Dimensions.get( 'window' );
const styles = StyleSheet.create( {
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 1
},
imageWrap: {
position: 'absolute',
backgroundColor: 'blue',
top: -( animationDistance / 2 ),
left: -( animationDistance / 2 ),
width: width + animationDistance,
height: height + animationDistance
},
image: {
width: width + animationDistance,
height: height + animationDistance
}
} );
Кто-нибудь видит, что это вызывает?