Почему мой Анимационный вид не остается в правильном месте в React Native?

Я создал "круг" (группа просмотров), которые переключаются с серого на желтый, когда движутся изображения. Круги начинают правильно преобразовываться, а затем возвращаются к первому пятну вместо того, чтобы идти к следующему кругу, чтобы указать, что вы находитесь на следующем изображении. Желтый круг всегда возвращается к первому месту, несмотря ни на что. Кто-нибудь знает, почему это может произойти? Как мне заставить его остаться в следующем месте?

ПОЖАЛУЙСТА, см. Это видео, которое я сделал из него: https://youtu.be/BCaSgNexPAs

Вот как я создаю и обрабатываю преобразования круглых представлений:

    let circleArray = [];

    if (this.state.imgArray) {
        this.state.imgArray.forEach((val, i) => {
            const scrollCircleVal = this.imgXPos.interpolate({
                inputRange: [deviceWidth * (i - 1), deviceWidth * (i + 1)],
                outputRange: [-8, 8],
                extrapolate: 'clamp',
            });

            const thisCircle = (
                <View
                    key={'circle' + i}
                    style={[
                        styles.track,
                        {
                            width: 8,
                            height: 8,
                            marginLeft: i === 0 ? 0 : CIRCLE_SPACE,
                            borderRadius: 75

                        },
                    ]}
                >
                    <Animated.View
                        style={[
                            styles.circle,
                            {
                                width: 8,
                                height: 8,
                                borderRadius: 75,
                                transform: [
                                    {translateX: scrollCircleVal},
                                ],
                                backgroundColor: '#FFD200'
                            },
                        ]}
                    />
                </View>
            );
            circleArray.push(thisCircle)
        });
    }

И вот мой код для того, как я обрабатываю изображение:

handleSwipe = (indexDirection) => {
    if (!this.state.imgArray[this.state.imgIndex + indexDirection]) {
        Animated.spring(this.imgXPos, {
            toValue: 0
        }).start();
        return;
    }

    this.setState((prevState) => ({
        imgIndex: prevState.imgIndex + indexDirection
    }), () => {
        this.imgXPos.setValue(indexDirection * this.width);
        Animated.spring(this.imgXPos, {
            toValue: 0
        }).start();
    });
}

imgPanResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: (e, gs) => {
        this.imgXPos.setValue(gs.dx);
    },
    onPanResponderRelease: (e, gs) => {
        this.width = Dimensions.get('window').width;
        const direction = Math.sign(gs.dx);

        if (Math.abs(gs.dx) > this.width * 0.4) {
            Animated.timing(this.imgXPos, {
                toValue: direction * this.width,
                duration: 250
            }).start(() => this.handleSwipe(-1 * direction));
        } else {
            Animated.spring(this.imgXPos, {
                toValue: 0
            }).start();
        }
    }
});

Html:

<Animated.Image 
    {...this.imgPanResponder.panHandlers}
    key={'image' + this.state.imgIndex}
    style={{left: this.imgXPos, height: '100%', width: '100%', borderRadius: 7}}
    resizeMethod={'scale'}
    resizeMode={'cover'}
    source={{uri: this.state.imgArray[this.state.imgIndex]}}
/>
<View style={styles.circleContainer}>
    {circleArray}
</View>

Ответ 1

Трудно сначала получить свой код, как и все в одном месте.

Сначала я предлагаю разбить код на более мелкие части: ImageView, CirclesView

Теперь, когда мы это сделаем, я хочу попытаться сделать CirclesView немного проще (если вы действительно не хотите, чтобы этот анимационный вид внутри круга).

Но из вашего кода я не видел разницы для "selectedImage" (imgIndex)

Поскольку он имеет расчеты для каждого индекса, но без ссылки на выбранный образ.

Грубый код шара Я бы подумал сделать с текущим кодом:

    let circleArray = [];

    if (this.state.imgArray) {
        this.state.imgArray.forEach((val, i) => {
            const scrollCircleVal = this.imgXPos.interpolate({
                inputRange: [deviceWidth * (i - 1), deviceWidth * (i + 1)],
                outputRange: [-8, 8],
                extrapolate: 'clamp',
            });

            const thisCircle = (
                <View
                    key={'circle' + i}
                    style={[
                        styles.track,
                        {
                            width: 8,
                            height: 8,
                            marginLeft: i === 0 ? 0 : CIRCLE_SPACE,
                            borderRadius: 75

                        },
                    ]}
                >

                   // LOOK AT THIS LINE BELOW

                   {this.state.imgIndex == i &&
                    <Animated.View
                        style={[
                            styles.circle,
                            {
                                width: 8,
                                height: 8,
                                borderRadius: 75,
                                transform: [
                                    {translateX: scrollCircleVal},
                                ],
                                backgroundColor: '#FFD200'
                            },
                        ]}
                    />}
                </View>
            );
            circleArray.push(thisCircle)
        });
    }

проверьте строку, которую я добавил над "анимированным" кругом для "выбранного" круга

Ответ 2

Я бы согласился с большинством уведомлений Tzook... но из того, что я вижу в коде (намерениях), все круги анимированы (но на самом деле затрагивается только одна пара - одна прячется, одна показывает) - анимация только выделенной не дает этого,

Я анимировал сотни "ползунков/галерей" во флеше;) - что с предыдущими/соседними/соседними изображениями - не следует анимировать одновременно?

Изображения с одинаковой шириной (или когда вы можете принимать поля между ними) легко, вы можете анимировать контейнер с 3 (или даже только 2) изображениями из более длинного (зацикленного, конечно?) Списка/массива. Это похоже на прокрутку виртуального списка.

С этими рабочими кругами тоже будет легко - оживить только 3 из них: prev/curr/next.

Простая анимация проста - только замена изображений в конце анимации. Это может выглядеть тяжелее с эффектами fe bouncing (когда изображение скользит больше/дальше, чем его целевая позиция, а следующий img должен быть видимым некоторое время), но вы можете просто поменять их раньше, сразу после распознавания направления.