簡體   English   中英

在第二個輸入上反應原生動畫PanResponder反向

[英]React Native Animated PanResponder reverse on second input

我將PanResponder與React Native API的Animated結合使用了一個組件。 我組件的代碼:

import React, { Component } from 'react';
import { Animated, PanResponder } from 'react-native';

import { SVG } from '../';
import { Icon, LockContainer, StatusCircle } from './styled';

class VehicleLock extends Component {
  state = {
    pan: new Animated.ValueXY({ x: 9, y: 16 }),
  };

  componentWillMount() {
    this.animatedValueY = 0;

    this.minYValue = 16;
    this.maxYValue = 175;

    this.state.pan.y.addListener((value) => {
      this.animatedValueY = value.value;
    });

    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponderCapture: () => true,
      onMoveShouldSetPanResponderCapture: () => true,

      onPanResponderGrant: (evt, gestureState) => {
        this.state.pan.setOffset({ x: 0, y: 0 });
        // this.state.pan.setOffset(this.state.pan.__getValue());
        this.state.pan.setValue({ x: 9, y: this.minYValue });
      },
      onPanResponderMove: (evt, gestureState) => {
        // deltaY: amount of pixels moved vertically since the beginning of the gesture
        let newY = gestureState.dy;

        if (newY < this.minYValue) {
          newY = this.minYValue;
        } else if (newY > this.maxYValue) {
          newY = this.maxYValue;
        }

        Animated.event([null, {
          dy: this.state.pan.y,
        }])(evt, {
          dy: newY,
        });
      },
      onPanResponderRelease: (evt, gestureState) => {
        let newY = this.minYValue;
        const releaseY = gestureState.dy;

        if (releaseY > 83) {
          newY = this.maxYValue;
        }

        Animated.spring(this.state.pan, {
          toValue: {
            x: 9,
            y: newY,
          },
        }).start();
      },
    });
  }

  componentWillUnmount() {
    this.state.pan.x.removeAllListeners();
    this.state.pan.y.removeAllListeners();
  }

  render() {
    const customStyles = {
      ...this.state.pan.getLayout(),
      position: 'absolute',
      zIndex: 10,
      transform: [
        {
          rotate: this.state.pan.y.interpolate({
            inputRange: [this.minYValue, this.maxYValue],
            outputRange: ['0deg', '180deg'],
          }),
        },
      ],
    };

    return (
      <LockContainer>
        <SVG icon="lock_open" width={16} height={21} />

        <Animated.View
          {...this.panResponder.panHandlers}
          style={customStyles}
        >
          <StatusCircle>
            <Icon>
              <SVG icon="arrow_down" width={23} height={23} />
            </Icon>
          </StatusCircle>
        </Animated.View>

        <SVG icon="lock_closed" width={16} height={21} />
      </LockContainer>
    );
  }
}

export default VehicleLock;

如您在我的代碼中看到的那樣,我為Y值設置了邊界動畫。 它必須保留在某些值之間的框中。 用戶一放開阻力,阻力就超過了最大Y值的一半,就動畫化為最大值。

這項工作沒有任何問題,但是在第二次互動中,我想撤消該操作。 因此,它必須上升,而不是下降。 不幸的是,釋放時Y值會重置。

正如您在代碼注釋中所看到的那樣,我知道運動是基於增量的,因此自交互開始以來已移動的Y值。 PanResponder在第二次拖動時將Animated.View捕捉回原始位置

雖然我不知道如何解決。 在這里您可以看到我當前的行為: 在此處輸入圖片說明

在第二個輸入上,元素將彈回到頂部。 這是預期的行為。 就像@jevakallio在他的評論中指出的那樣,您可以在onPanResponderGrant中的偏移量中重置值。 當我這樣做(注釋掉)時,該元素將重置值,但是在第二次交互時,它將在容器外部進行動畫處理。 因此,在這種情況下, 0maxYValue ,它maxYValue容器外部的175動畫到底部。

如何使反向動畫從外部回到頂部? 我似乎不明白這一點。 提前致謝!

根據Panresponder文檔onPanResponderGrant應該指示手勢的開始。 因此,如果此時設置this.state.pan.setOffsetthis.state.pan.setValue ,它將在每個手勢開始時重置。 onPanResponderGrant嘗試console.log,看看會發生什么。

另外,實現PanResponder的父組件或包裝組件可能會干擾您的PanResponder。 這可能是進行故障排除的另一個很好的起點。

從PanResponder文檔中:

onPanResponderGrant: (evt, gestureState) => {
    // The gesture has started. Show visual feedback so the user knows
    // what is happening!

    // gestureState.d{x,y} will be set to zero now
  },

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM