mirror of
https://github.com/status-im/react-native.git
synced 2025-02-10 16:36:25 +00:00
[ReactNative] PanResponder documentation
This commit is contained in:
parent
8679c0bc96
commit
f6fc7f37b6
@ -18,66 +18,143 @@ var currentCentroidX = TouchHistoryMath.currentCentroidX;
|
|||||||
var currentCentroidY = TouchHistoryMath.currentCentroidY;
|
var currentCentroidY = TouchHistoryMath.currentCentroidY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* `PanResponder` reconciles several touches into a single gesture. It makes
|
||||||
|
* single-touch gestures resilient to extra touches, and can be used to
|
||||||
|
* recognize simple multi-touch gestures.
|
||||||
*
|
*
|
||||||
* +----------------------------+ +--------------------------------+
|
* It provides a predictable wrapper of the responder handlers provided by the
|
||||||
* | ResponderTouchHistoryStore | |TouchHistoryMath |
|
* [gesture responder system](/react-native/docs/gesture-responder-system.html).
|
||||||
* +----------------------------+ +----------+---------------------+
|
* For each handler, it provides a new `gestureState` object alongside the
|
||||||
* |Global store of touchHistory| |Allocation-less math util |
|
* normal event.
|
||||||
* |including activeness, start | |on touch history (centroids |
|
|
||||||
* |position, prev/cur position.| |and multitouch movement etc) |
|
|
||||||
* | | | |
|
|
||||||
* +----^-----------------------+ +----^---------------------------+
|
|
||||||
* | |
|
|
||||||
* | (records relevant history |
|
|
||||||
* | of touches relevant for |
|
|
||||||
* | implementing higher level |
|
|
||||||
* | gestures) |
|
|
||||||
* | |
|
|
||||||
* +----+-----------------------+ +----|---------------------------+
|
|
||||||
* | ResponderEventPlugin | | | Your App/Component |
|
|
||||||
* +----------------------------+ +----|---------------------------+
|
|
||||||
* |Negotiates which view gets | Low level | | High level |
|
|
||||||
* |onResponderMove events. | events w/ | +-+-------+ events w/ |
|
|
||||||
* |Also records history into | touchHistory| | Pan | multitouch + |
|
|
||||||
* |ResponderTouchHistoryStore. +---------------->Responder+-----> accumulative|
|
|
||||||
* +----------------------------+ attached to | | | distance and |
|
|
||||||
* each event | +---------+ velocity. |
|
|
||||||
* | |
|
|
||||||
* | |
|
|
||||||
* +--------------------------------+
|
|
||||||
*
|
*
|
||||||
|
* A `gestureState` object has the following:
|
||||||
*
|
*
|
||||||
|
* - `stateID` - ID of the gestureState- persisted as long as there at least
|
||||||
|
* one touch on screen
|
||||||
|
* - `moveX` - the latest screen coordinates of the recently-moved touch
|
||||||
|
* - `moveY` - the latest screen coordinates of the recently-moved touch
|
||||||
|
* - `x0` - the screen coordinates of the responder grant
|
||||||
|
* - `y0` - the screen coordinates of the responder grant
|
||||||
|
* - `dx` - accumulated distance of the gesture since the touch started
|
||||||
|
* - `dy` - accumulated distance of the gesture since the touch started
|
||||||
|
* - `vx` - current velocity of the gesture
|
||||||
|
* - `vy` - current velocity of the gesture
|
||||||
|
* - `numberActiveTouches` - Number of touches currently on screeen
|
||||||
*
|
*
|
||||||
* Gesture that calculates cumulative movement over time in a way that just
|
* ### Basic Usage
|
||||||
* "does the right thing" for multiple touches. The "right thing" is very
|
|
||||||
* nuanced. When moving two touches in opposite directions, the cumulative
|
|
||||||
* distance is zero in each dimension. When two touches move in parallel five
|
|
||||||
* pixels in the same direction, the cumulative distance is five, not ten. If
|
|
||||||
* two touches start, one moves five in a direction, then stops and the other
|
|
||||||
* touch moves fives in the same direction, the cumulative distance is ten.
|
|
||||||
*
|
*
|
||||||
* This logic requires a kind of processing of time "clusters" of touch events
|
* ```
|
||||||
* so that two touch moves that essentially occur in parallel but move every
|
* componentWillMount: function() {
|
||||||
* other frame respectively, are considered part of the same movement.
|
* this._panGesture = PanResponder.create({
|
||||||
|
* // Ask to be the responder:
|
||||||
|
* onStartShouldSetPanResponder: (evt, gestureState) => true,
|
||||||
|
* onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
|
||||||
|
* onMoveShouldSetPanResponder: (evt, gestureState) => true,
|
||||||
|
* onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
|
||||||
*
|
*
|
||||||
* Explanation of some of the non-obvious fields:
|
* onPanResponderGrant: (evt, gestureState) => {
|
||||||
|
* // The guesture has started. Show visual feedback so the user knows
|
||||||
|
* // what is happening!
|
||||||
*
|
*
|
||||||
* - moveX/moveY: If no move event has been observed, then `(moveX, moveY)` is
|
* // gestureState.{x,y}0 will be set to zero now
|
||||||
* invalid. If a move event has been observed, `(moveX, moveY)` is the
|
* },
|
||||||
* centroid of the most recently moved "cluster" of active touches.
|
* onPanResponderMove: (evt, gestureState) => {
|
||||||
* (Currently all move have the same timeStamp, but later we should add some
|
* // The most recent move distance is gestureState.move{X,Y}
|
||||||
* threshold for what is considered to be "moving"). If a palm is
|
*
|
||||||
* accidentally counted as a touch, but a finger is moving greatly, the palm
|
* // The accumulated gesture distance since becoming responder is
|
||||||
* will move slightly, but we only want to count the single moving touch.
|
* // gestureState.d{x,y}
|
||||||
* - x0/y0: Centroid location (non-cumulative) at the time of becoming
|
* },
|
||||||
* responder.
|
* onResponderTerminationRequest: (evt, gestureState) => true,
|
||||||
* - dx/dy: Cumulative touch distance - not the same thing as sum of each touch
|
* onPanResponderRelease: (evt, gestureState) => {
|
||||||
* distance. Accounts for touch moves that are clustered together in time,
|
* // The user has released all touches while this view is the
|
||||||
* moving the same direction. Only valid when currently responder (otherwise,
|
* // responder. This typically means a gesture has succeeded
|
||||||
* it only represents the drag distance below the threshold).
|
* },
|
||||||
* - vx/vy: Velocity.
|
* onPanResponderTerminate: (evt, gestureState) => {
|
||||||
|
* // Another component has become the responder, so this gesture
|
||||||
|
* // should be cancelled
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
* },
|
||||||
|
*
|
||||||
|
* render: function() {
|
||||||
|
* return (
|
||||||
|
* <View {...this._panResponder.panHandlers} />
|
||||||
|
* );
|
||||||
|
* },
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ### Working Example
|
||||||
|
*
|
||||||
|
* To see it in action, try the
|
||||||
|
* [PanResponder example in UIExplorer](https://github.com/facebook/react-native/blob/master/Examples/UIExplorer/ResponderExample.js)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var PanResponder = {
|
var PanResponder = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A graphical explanation of the touch data flow:
|
||||||
|
*
|
||||||
|
* +----------------------------+ +--------------------------------+
|
||||||
|
* | ResponderTouchHistoryStore | |TouchHistoryMath |
|
||||||
|
* +----------------------------+ +----------+---------------------+
|
||||||
|
* |Global store of touchHistory| |Allocation-less math util |
|
||||||
|
* |including activeness, start | |on touch history (centroids |
|
||||||
|
* |position, prev/cur position.| |and multitouch movement etc) |
|
||||||
|
* | | | |
|
||||||
|
* +----^-----------------------+ +----^---------------------------+
|
||||||
|
* | |
|
||||||
|
* | (records relevant history |
|
||||||
|
* | of touches relevant for |
|
||||||
|
* | implementing higher level |
|
||||||
|
* | gestures) |
|
||||||
|
* | |
|
||||||
|
* +----+-----------------------+ +----|---------------------------+
|
||||||
|
* | ResponderEventPlugin | | | Your App/Component |
|
||||||
|
* +----------------------------+ +----|---------------------------+
|
||||||
|
* |Negotiates which view gets | Low level | | High level |
|
||||||
|
* |onResponderMove events. | events w/ | +-+-------+ events w/ |
|
||||||
|
* |Also records history into | touchHistory| | Pan | multitouch + |
|
||||||
|
* |ResponderTouchHistoryStore. +---------------->Responder+-----> accumulative|
|
||||||
|
* +----------------------------+ attached to | | | distance and |
|
||||||
|
* each event | +---------+ velocity. |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* +--------------------------------+
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Gesture that calculates cumulative movement over time in a way that just
|
||||||
|
* "does the right thing" for multiple touches. The "right thing" is very
|
||||||
|
* nuanced. When moving two touches in opposite directions, the cumulative
|
||||||
|
* distance is zero in each dimension. When two touches move in parallel five
|
||||||
|
* pixels in the same direction, the cumulative distance is five, not ten. If
|
||||||
|
* two touches start, one moves five in a direction, then stops and the other
|
||||||
|
* touch moves fives in the same direction, the cumulative distance is ten.
|
||||||
|
*
|
||||||
|
* This logic requires a kind of processing of time "clusters" of touch events
|
||||||
|
* so that two touch moves that essentially occur in parallel but move every
|
||||||
|
* other frame respectively, are considered part of the same movement.
|
||||||
|
*
|
||||||
|
* Explanation of some of the non-obvious fields:
|
||||||
|
*
|
||||||
|
* - moveX/moveY: If no move event has been observed, then `(moveX, moveY)` is
|
||||||
|
* invalid. If a move event has been observed, `(moveX, moveY)` is the
|
||||||
|
* centroid of the most recently moved "cluster" of active touches.
|
||||||
|
* (Currently all move have the same timeStamp, but later we should add some
|
||||||
|
* threshold for what is considered to be "moving"). If a palm is
|
||||||
|
* accidentally counted as a touch, but a finger is moving greatly, the palm
|
||||||
|
* will move slightly, but we only want to count the single moving touch.
|
||||||
|
* - x0/y0: Centroid location (non-cumulative) at the time of becoming
|
||||||
|
* responder.
|
||||||
|
* - dx/dy: Cumulative touch distance - not the same thing as sum of each touch
|
||||||
|
* distance. Accounts for touch moves that are clustered together in time,
|
||||||
|
* moving the same direction. Only valid when currently responder (otherwise,
|
||||||
|
* it only represents the drag distance below the threshold).
|
||||||
|
* - vx/vy: Velocity.
|
||||||
|
*/
|
||||||
|
|
||||||
_initializeGestureState: function(gestureState) {
|
_initializeGestureState: function(gestureState) {
|
||||||
gestureState.moveX = 0;
|
gestureState.moveX = 0;
|
||||||
gestureState.moveY = 0;
|
gestureState.moveY = 0;
|
||||||
@ -147,29 +224,29 @@ var PanResponder = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} config Enhanced versions of all of the responder callbacks
|
* @param {object} config Enhanced versions of all of the responder callbacks
|
||||||
* that accept not only the typical `ResponderSyntheticEvent`, but also the
|
* that provide not only the typical `ResponderSyntheticEvent`, but also the
|
||||||
* `PanResponder` gesture state. Simply replace the word `Responder` with
|
* `PanResponder` gesture state. Simply replace the word `Responder` with
|
||||||
* `PanResponder` in each of the typical `onResponder*` callbacks. For
|
* `PanResponder` in each of the typical `onResponder*` callbacks. For
|
||||||
* example, the `config` object would look like:
|
* example, the `config` object would look like:
|
||||||
*
|
*
|
||||||
* - onMoveShouldSetPanResponder: (e, gestureState) => {...}
|
* - `onMoveShouldSetPanResponder: (e, gestureState) => {...}`
|
||||||
* - onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}
|
* - `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}`
|
||||||
* - onStartShouldSetPanResponder: (e, gestureState) => {...}
|
* - `onStartShouldSetPanResponder: (e, gestureState) => {...}`
|
||||||
* - onStartShouldSetPanResponderCapture: (e, gestureState) => {...}
|
* - `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}`
|
||||||
* - onPanResponderReject: (e, gestureState) => {...}
|
* - `onPanResponderReject: (e, gestureState) => {...}`
|
||||||
* - onPanResponderGrant: (e, gestureState) => {...}
|
* - `onPanResponderGrant: (e, gestureState) => {...}`
|
||||||
* - onPanResponderStart: (e, gestureState) => {...}
|
* - `onPanResponderStart: (e, gestureState) => {...}`
|
||||||
* - onPanResponderEnd: (e, gestureState) => {...}
|
* - `onPanResponderEnd: (e, gestureState) => {...}`
|
||||||
* - onPanResponderRelease: (e, gestureState) => {...}
|
* - `onPanResponderRelease: (e, gestureState) => {...}`
|
||||||
* - onPanResponderMove: (e, gestureState) => {...}
|
* - `onPanResponderMove: (e, gestureState) => {...}`
|
||||||
* - onPanResponderTerminate: (e, gestureState) => {...}
|
* - `onPanResponderTerminate: (e, gestureState) => {...}`
|
||||||
* - onPanResponderTerminationRequest: (e, gestureState) => {...}
|
* - `onPanResponderTerminationRequest: (e, gestureState) => {...}`
|
||||||
*
|
*
|
||||||
* - In general, for events that have capture equivalents, we update the
|
* In general, for events that have capture equivalents, we update the
|
||||||
* gestureState once in the capture phase and can use it in the bubble phase
|
* gestureState once in the capture phase and can use it in the bubble phase
|
||||||
* as well.
|
* as well.
|
||||||
*
|
*
|
||||||
* - Be careful with onStartShould* callbacks. They only reflect updated
|
* Be careful with onStartShould* callbacks. They only reflect updated
|
||||||
* `gestureState` for start/end events that bubble/capture to the Node.
|
* `gestureState` for start/end events that bubble/capture to the Node.
|
||||||
* Once the node is the responder, you can rely on every start/end event
|
* Once the node is the responder, you can rely on every start/end event
|
||||||
* being processed by the gesture and `gestureState` being updated
|
* being processed by the gesture and `gestureState` being updated
|
||||||
|
Loading…
x
Reference in New Issue
Block a user