Skip to content

Commit 4146b16

Browse files
committed
Add PanResponder examples to docs
1 parent fe013b3 commit 4146b16

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Meta, Props, Preview, Story } from '@storybook/addon-docs/blocks';
2+
import * as Stories from './examples';
3+
4+
<Meta title="APIs|PanResponder" />
5+
6+
# PanResponder
7+
8+
## Examples
9+
10+
<Preview withSource='none'>
11+
<Story name="draggableCircle">
12+
<Stories.draggableCircle />
13+
</Story>
14+
</Preview>
15+
16+
<Preview withSource='none'>
17+
<Story name="locationXY">
18+
<Stories.locationXY />
19+
</Story>
20+
</Preview>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/**
2+
* @flow
3+
*/
4+
5+
import React, { PureComponent } from 'react';
6+
import { PanResponder, StyleSheet, View } from 'react-native';
7+
8+
const CIRCLE_SIZE = 80;
9+
10+
export default class DraggableCircle extends PureComponent {
11+
_panResponder = {};
12+
_previousLeft = 0;
13+
_previousTop = 0;
14+
_circleStyles = {};
15+
circle = (null: ?{ setNativeProps(props: Object): void });
16+
17+
constructor() {
18+
super();
19+
this._panResponder = PanResponder.create({
20+
onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
21+
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
22+
onPanResponderGrant: this._handlePanResponderGrant,
23+
onPanResponderMove: this._handlePanResponderMove,
24+
onPanResponderRelease: this._handlePanResponderEnd,
25+
onPanResponderTerminate: this._handlePanResponderEnd
26+
});
27+
this._previousLeft = 20;
28+
this._previousTop = 84;
29+
this._circleStyles = {
30+
style: {
31+
left: this._previousLeft,
32+
top: this._previousTop,
33+
backgroundColor: 'green'
34+
}
35+
};
36+
}
37+
38+
componentDidMount() {
39+
this._updateNativeStyles();
40+
}
41+
42+
render() {
43+
return (
44+
<View style={styles.container}>
45+
<View ref={this._setCircleRef} style={styles.circle} {...this._panResponder.panHandlers} />
46+
</View>
47+
);
48+
}
49+
50+
_setCircleRef = circle => {
51+
this.circle = circle;
52+
};
53+
54+
_highlight() {
55+
this._circleStyles.style.backgroundColor = 'blue';
56+
this._updateNativeStyles();
57+
}
58+
59+
_unHighlight() {
60+
this._circleStyles.style.backgroundColor = 'green';
61+
this._updateNativeStyles();
62+
}
63+
64+
_updateNativeStyles() {
65+
this.circle && this.circle.setNativeProps(this._circleStyles);
66+
}
67+
68+
_handleStartShouldSetPanResponder = (e: Object, gestureState: Object): boolean => {
69+
// Should we become active when the user presses down on the circle?
70+
return true;
71+
};
72+
73+
_handleMoveShouldSetPanResponder = (e: Object, gestureState: Object): boolean => {
74+
// Should we become active when the user moves a touch over the circle?
75+
return true;
76+
};
77+
78+
_handlePanResponderGrant = (e: Object, gestureState: Object) => {
79+
this._highlight();
80+
};
81+
82+
_handlePanResponderMove = (e: Object, gestureState: Object) => {
83+
this._circleStyles.style.left = this._previousLeft + gestureState.dx;
84+
this._circleStyles.style.top = this._previousTop + gestureState.dy;
85+
this._updateNativeStyles();
86+
};
87+
88+
_handlePanResponderEnd = (e: Object, gestureState: Object) => {
89+
this._unHighlight();
90+
this._previousLeft += gestureState.dx;
91+
this._previousTop += gestureState.dy;
92+
};
93+
}
94+
95+
const styles = StyleSheet.create({
96+
circle: {
97+
width: CIRCLE_SIZE,
98+
height: CIRCLE_SIZE,
99+
borderRadius: CIRCLE_SIZE / 2,
100+
position: 'absolute',
101+
left: 0,
102+
top: 0,
103+
touchAction: 'none'
104+
},
105+
container: {
106+
flex: 1,
107+
minHeight: 400,
108+
paddingTop: 64
109+
}
110+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { Component } from 'react';
2+
import { StyleSheet, View, PanResponder } from 'react-native';
3+
4+
export default class LocationXY extends Component {
5+
constructor() {
6+
super();
7+
this.state = { translateX: 0 };
8+
this.panResponder = PanResponder.create({
9+
onStartShouldSetPanResponder: () => true,
10+
onStartShouldSetPanResponderCapture: () => true,
11+
onPanResponderMove: this._handlePanResponderMove,
12+
onPanResponderTerminationRequest: () => true
13+
});
14+
}
15+
16+
_handlePanResponderMove = (e, gestureState) => {
17+
console.log(e.nativeEvent.locationX, e.nativeEvent.locationY);
18+
this.setState(state => ({
19+
...state,
20+
translateX: gestureState.dx
21+
}));
22+
};
23+
24+
render() {
25+
const transform = { transform: [{ translateX: this.state.translateX }] };
26+
return (
27+
<View style={styles.app}>
28+
<View style={styles.outer} {...this.panResponder.panHandlers}>
29+
<View style={[styles.inner, transform]} />
30+
</View>
31+
</View>
32+
);
33+
}
34+
}
35+
36+
const styles = StyleSheet.create({
37+
app: {
38+
justifyContent: 'center',
39+
alignItems: 'center'
40+
},
41+
outer: {
42+
width: 250,
43+
height: 50,
44+
backgroundColor: 'skyblue'
45+
},
46+
inner: {
47+
width: 30,
48+
height: 30,
49+
backgroundColor: 'lightblue'
50+
}
51+
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as draggableCircle } from './DraggableCircle';
2+
export { default as locationXY } from './LocationXY';

0 commit comments

Comments
 (0)