为什么此动画在第一次通过时不能正常工作,而在所有后续通过时却不能正常工作? (反应本机)

时间:2019-02-27 23:34:54

标签: ios reactjs react-native animation

我使用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
    }
} );

有人看到是什么原因造成的吗?

0 个答案:

没有答案