React Native:如何通过反弹在屏幕上滑动某些内容?

时间:2016-12-24 16:49:45

标签: animation react-native

我正在尝试制作可以在屏幕上滑动叠加层的内容。

这是我到目前为止使用的PanResponder,但我觉得它不是很干净。这是我第一次使用它,所以我想知道是否有更好的方法来做到这一点。

我需要为绿色部分制作动画,所以我想在不使用包的情况下手动构建它。

我的组件看起来像这样(严重复制了这个人: https://github.com/brentvatne/react-native-animated-demo-tinder/blob/master/index.ios.js

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  View,
  PanResponder,
  Animated,
  Dimensions,
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignSelf: 'stretch',
    backgroundColor: '#000000',
  },
  overlay: {
    flex: 1,
    alignSelf: 'stretch',
    backgroundColor: '#0000ff',
  },
  video: {
    position: 'absolute',
    backgroundColor: '#00ff00',
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
  }
});

function clamp(value, min, max) {
  return min < max
    ? (value < min ? min : value > max ? max : value)
    : (value < max ? max : value > min ? min : value)
}

export default class EdmundApp extends Component {

  constructor(props) {
    super(props);
    this.state = {
      pan: new Animated.ValueXY(),
    };
  }

  componentWillMount() {
    this._panResponder = PanResponder.create({
      onMoveShouldSetResponderCapture: () => true,
      onMoveShouldSetPanResponderCapture: () => true,

      onPanResponderGrant: (e, gestureState) => {
        this.state.pan.setOffset({x: this.state.pan.x._value, y: 0});
        this.state.pan.setValue({x: 0, y: 0});
      },

      onPanResponderMove: Animated.event([
        null, {dx: this.state.pan.x, dy: 0},
      ]),

      onPanResponderRelease: (e, {vx, vy}) => {
        this.state.pan.flattenOffset();
        if (vx >= 0) {
          velocity = clamp(vx, 3, 5);
        } else if (vx < 0) {
          velocity = clamp(vx * -1, 3, 5) * -1;
        }

        if (Math.abs(this.state.pan.x._value) > 150) {
          Animated.decay(this.state.pan, {
            velocity: {x: velocity, y: vy},
            deceleration: 0.98
          }).start()
        } else {
          Animated.spring(this.state.pan, {
            toValue: {x: 0, y: 0},
            friction: 4
          }).start()
        }
      }
    });
  }

  render() {
    let { pan } = this.state;
    let translateX = pan.x;
    let swipeStyles = {transform: [{translateX}]};
    return (
      <View style={styles.container}>
        <View style={styles.video}></View>
        <Animated.View style={[styles.overlay, swipeStyles]} {...this._panResponder.panHandlers}>
        </Animated.View>
      </View>
    );
  }
}

AppRegistry.registerComponent('EdmundApp', () => EdmundApp);

enter image description here

1 个答案:

答案 0 :(得分:1)

请完成此https://github.com/oblador/react-native-animatable

有弹跳和退出选项,这对您有帮助。