Как перевести смещение вида на основе текущей позиции перетаскивания родителя - PullRequest
0 голосов
/ 06 января 2019

У меня есть супер специфический случай, который как бы сбивает с толку меня от того, как математика должна работать, чтобы заставить это работать

У меня есть эта карта на странице

enter image description here

Который отображается с этими стилями ...

-------- main card --------
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height,
shadowColor: "#455B63",
shadowOffset: {
  width: 0,
  height: 0,
},
shadowOpacity: 0.33,
shadowRadius: 16,
borderBottomLeftRadius: 12,
borderBottomRightRadius: 12

-------- content view --------
backgroundColor: '#fff',
paddingVertical: 14,
paddingHorizontal: 20,
height: height * 2

С этой анимацией, прикрепленной к ней ...

Animated.spring(this.state.placeCard,{
    toValue: {x: 0, y: deviceHeight - placeCardClosedHeight},
    duration: 350,
}).start();

Представление содержимого имеет это состояние анимации, установленное в состоянии

new Animated.ValueXY({x: 0, y: -(Math.round(deviceHeight / 2) - 160)})

И я пытаюсь заставить его анимировать этот макет

enter image description here

Панхендлер, который я настроил для обработки общих стилей карт, это

this._placeCardPanResponder = PanResponder.create({
  onMoveShouldSetPanResponderCapture: (evt, gestureState) => gestureState.dx != 0 && gestureState.dy != 0,
  onPanResponderGrant: (evt, gestureState) => {
    this.setState({
      placeCardTopOffset: this.state.placeCard.__getValue().y
    })
  },
  onPanResponderMove: (evt, gestureState) => {
    let y = gestureState.dy;
    const { placeCardTopOffset } = this.state;
    if (y + placeCardTopOffset <= 0) {
      y = 0
    } else if (y + placeCardTopOffset >= deviceHeight - placeCardClosedHeight) {
      y = deviceHeight - placeCardClosedHeight
    } else {
      y = y + placeCardTopOffset;
    }
    this.state.placeCard.setValue({x: 0, y});
  },
  onPanResponderRelease: (evt, gestureState) => {
    if (gestureState.dy < 0) {
      if (this.state.placeCard.__getValue().y > 0) {
        Animated.timing(
          this.state.placeCard,
          {
            toValue: {x: 0, y: 0},
            duration: 175,
          }
        ).start();
      }
    }
    if (gestureState.dy > 0) {
      if (this.state.placeCard.__getValue().y < deviceHeight - placeCardClosedHeight) {
        Animated.timing(
          this.state.placeCard,
          {
            toValue: {x: 0, y: deviceHeight - placeCardClosedHeight},
            duration: 175,
          }
        ).start();
      }
    }
  }
});

Когда на странице полноразмерная карта, представление контента будет анимировано примерно так

Animated.timing(
  this.state.placeCardContent,
  {
    toValue: {x: 0, y: 0},
    duration: 175,
  }
).start();

У меня есть настройка закуски, чтобы показать это

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

https://snack.expo.io/B1lhq5Rb4

1 Ответ

0 голосов
/ 07 января 2019

Я не обращал внимания на тот факт, что react-native API *1001* имеет функцию .interpolate(), которая была разработана для этой переменной задачи.

Вот код для этой работы ...

<Animated.View style={{...style.placeCardContent, transform: [{
    translateX: 0
},{
    translateY: this.state.placeCard.y.interpolate({
        inputRange: [0, deviceHeight - placeCardClosedHeight],
        outputRange: [0, -(Math.round(deviceHeight / 2) - 160)]
    })
}]}}>

Вы можете увидеть это на примере закуски

https://snack.expo.io/@jordanr/carddrag

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...