美文网首页程序员React Native学习
react native 手势驱动封装 类似 ios的Assis

react native 手势驱动封装 类似 ios的Assis

作者: JsLin_ | 来源:发表于2018-10-12 23:46 被阅读8次

效果图:


pan.gif

相关代码:

'use strict';

import React, { Component } from 'react';
import {
  View,
  PanResponder,
  StyleSheet,
} from 'react-native';
import PropTypes from 'prop-types';
import ViewUtil from '../utils/View';
/**
 * 使用方法
 * 
 * 
 * import PanResponderView from "../components/panResponder";
 * 
     <PanResponderView
       toachStyle={styles.toachStyle}
       />

 */
let _previousLeft = 0;
let _previousTop = 0;

let lastLeft = 0;
let lastTop = 0;

export default class Radio extends Component {
  static defaultProps = {
    PanSize: 80,
    PanStyle: {
      width: 80,
      height: 80,
      borderRadius: 80 / 2,
      backgroundColor: 'yellow',
      position: 'absolute',
    },
    defalutStyle:{
      backgroundColor:"yellow"
    },
  };
  static propTypes = {
    PanSize: PropTypes.number,  //手势驱动宽度
    PanDom: PropTypes.element,   //手势区自定义dom
    PanStyle: PropTypes.any,    //手势最外层view样式
    toachStyle: PropTypes.any,    //触摸反馈样式
    defalutStyle:PropTypes.any  //默认状态下的样式

  };

  constructor(props) {
    super(props);
    this.state = {
      style: this.props.defalutStyle,
    }
    this.onStartShouldSetPanResponder = this.onStartShouldSetPanResponder.bind(this);
    this.onMoveShouldSetPanResponder = this.onMoveShouldSetPanResponder.bind(this);
    this.onPanResponderGrant = this.onPanResponderGrant.bind(this);
    this.onPanResponderMove = this.onPanResponderMove.bind(this);
    this.onPanResponderEnd = this.onPanResponderEnd.bind(this);
  }
  //用户开始触摸屏幕的时候,是否愿意成为响应者;
  onStartShouldSetPanResponder(evt, gestureState) {
    return true;
  }
  //在每一个触摸点开始移动的时候,再询问一次是否响应触摸交互;
  onMoveShouldSetPanResponder(evt, gestureState) {
    return true;
  }
  // 开始手势操作。给用户一些视觉反馈,让他们知道发生了什么事情!
  onPanResponderGrant(evt, gestureState) {
    this.setState({
      style:
      {
        ...StyleSheet.flatten(this.props.toachStyle),
        left: _previousLeft,
        top: _previousTop,
      }
    });
  }
  // 最近一次的移动距离为gestureState.move{X,Y}
  onPanResponderMove(evt, gestureState) {
    const { PanSize, toachStyle } = this.props;
    _previousLeft = lastLeft + gestureState.dx;
    _previousTop = lastTop + gestureState.dy;

    if (_previousLeft <= 0) {
      _previousLeft = 0;
    }
    if (_previousTop <= 0) {
      _previousTop = 0;
    }
    if (_previousLeft >= ViewUtil.size.width - PanSize) {
      _previousLeft = ViewUtil.size.width - PanSize;
    }
    if (_previousTop >= ViewUtil.size.height - PanSize) {
      _previousTop = ViewUtil.size.height - PanSize;
    }

    //实时更新
    this.setState({
      style:
      {
        ...StyleSheet.flatten(toachStyle),
        left: _previousLeft,
        top: _previousTop,
      }
    });
  }
  // 用户放开了所有的触摸点,且此时视图已经成为了响应者。
  // 一般来说这意味着一个手势操作已经成功完成。
  onPanResponderEnd(evt, gestureState) {

    lastLeft = _previousLeft;
    lastTop = _previousTop;

    this.changePosition();
  }

  /**
   根据位置做出相应处理
  **/
  changePosition() {
    const { PanSize,defalutStyle } = this.props;
    if (_previousLeft + PanSize / 2 <= ViewUtil.size.width / 2) {
      //left
      _previousLeft = lastLeft = 0;

      this.setState({
        style:
        {
          ...StyleSheet.flatten(defalutStyle),
          left: _previousLeft,
          top: _previousTop,
        }
      });
    } else {
      _previousLeft = lastLeft = ViewUtil.size.width - PanSize;

      this.setState({
        style:
        {
          ...StyleSheet.flatten(defalutStyle),
          left: _previousLeft,
          top: _previousTop,
        }
      });
    }
  }

  componentWillMount(evt, gestureState) {
    this._panResponder = PanResponder.create({
      onStartShouldSetPanResponder: this.onStartShouldSetPanResponder,
      onMoveShouldSetPanResponder: this.onMoveShouldSetPanResponder,
      onPanResponderGrant: this.onPanResponderGrant,
      onPanResponderMove: this.onPanResponderMove,
      onPanResponderRelease: this.onPanResponderEnd,
      onPanResponderTerminate: this.onPanResponderEnd,
    });
  }
  render() {
    const { PanDom, PanStyle } = this.props;

    return (
      <View
        {...this._panResponder.panHandlers}
        style={[PanStyle, this.state.style]}>
        {PanDom}
      </View>
    );
  }
}


相关文章

网友评论

    本文标题:react native 手势驱动封装 类似 ios的Assis

    本文链接:https://www.haomeiwen.com/subject/cbynaftx.html