Как правильно установить новые координаты вида после анимации перевода в реагирующем? - PullRequest
0 голосов
/ 24 мая 2019

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

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

Результат поиска, в разработке Android (что, очевидно, не в моем случае), кажется, метод setFillAfter, который устанавливает координаты после анимации.

Мой вопрос заключается в том, как установить местоположение (например, значения left / top) для конечной переведенной точки, чтобы последовательная анимация начиналась с точки, оставленной предыдущим переводом.

Экспо-закуска для блока кода ниже здесь .

import * as React from 'react';
import { Image, StyleSheet, ImageBackground } from 'react-native';

import * as Animatable from 'react-native-animatable';
import { PanGestureHandler, State } from 'react-native-gesture-handler';

import testImg from './test.png';
import backImg from './back.png';

export default class App extends React.Component {
    onTestMove(event) {
        this.testAnimRef.transitionTo({
            translateX: event.nativeEvent.translationX,
            translateY: event.nativeEvent.translationY,
        }, 0);

    }
    render() {
        return (
            <ImageBackground source={backImg} style={{ flex: 1 }} >
                <PanGestureHandler
                    key={`test`}
                    onGestureEvent={(e) => { this.onTestMove(e) }}
                    onHandlerStateChange={e => { }}
                >
                    <Animatable.View style={styles._animatable_view}
                        ref={((ref) => { this.testAnimRef = ref }).bind(this)}
                        useNativeDriver={true}
                    >
                        <Image source={testImg} style={styles._image} />
                    </Animatable.View>
                </PanGestureHandler>
            </ImageBackground>
        );
    }
}

const styles = StyleSheet.create({
    _image: {
        width: 50,
        height: 25,
        resizeMode: 'contain',
        backgroundColor: 'black',
        borderColor: 'gainsboro',
        borderWidth: 2,
    },
    _animatable_view: {
        position: "absolute",
        top: 200,
        left: 100,
    },
});

1 Ответ

1 голос
/ 18 июля 2019

У меня возникла та же проблема, когда я пытался перемещаться по некоторым картам в представлении, и при дальнейшем перетаскивании они возвращались к исходному состоянию.

Моя теория заключается в том, что хотя переведенное представление будет переводить свои координаты x / y, это не будет применяться к родителю этого представления, и поэтому анимированное событие, переданное из этого компонента, изначально будет иметь исходныйкоординаты (убей меня, если я ошибаюсь)

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

  _onHandleGesture: any
  constructor(props: OwnProps) {
    super(props)
    this.state = {
      animationValue: new Animated.ValueXY({ x: 0, y: 0 }),
      initialOffset: { x: 0, y: 0 },
    }
    this._onHandleGesture = (e: PanGestureHandlerGestureEvent) => {
      this.state.animationValue.setValue({
        x: e.nativeEvent.translationX + this.state.initialOffset.x, <- add initial offset to coordinates passed
        y: e.nativeEvent.translationY + this.state.initialOffset.y,
      })
    }
  }

  _acceptCard = (cardValue: number) => {
    const { targetLocation, onAccept } = this.props

    const { x, y } = targetLocation

    onAccept(cardValue)

    Animated.spring(this.state.animationValue, {
  // Some animation here
    }).start(() => {
      this.setState({ initialOffset: targetLocation }) // <- callback to set state value for next animation start
    })
  }

и метод рендеринга

  <PanGestureHandler
        onHandlerStateChange={this.onPanHandlerStateChange}
        onGestureEvent={this._onHandleGesture}
        failOffsetX={[-xThreshold, xThreshold]}
      >
        <Animated.View
          style={{
            position: "absolute",
            left: 0,
            top: 0,
            transform: [{ translateX: this.state.animationValue.x }, { translateY: this.state.animationValue.y }],
          }}
        >
          <CardTile size={size} content={content} layout={layout} backgroundImage={backgroundImage} shadow={shadow} />
        </Animated.View>
      </PanGestureHandler>

Этот пример основан на библиотеке реагировать на собственный жест-обработчик, но концепция должна применяться к другим решениям.Не знаю, рекомендуется ли этот способ, хотя он и функционален.

Надеюсь, это поможет!

...