Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7ce8cd7

Browse files
committed
Updates Tue July 7th and Wed July 8th including Animated
2 parents 57513fd + fd2cb76 commit 7ce8cd7

File tree

89 files changed

+5463
-315
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+5463
-315
lines changed
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
/**
2+
* The examples provided by Facebook are for non-commercial testing and
3+
* evaluation purposes only.
4+
*
5+
* Facebook reserves all rights not expressly granted.
6+
*
7+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
10+
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
11+
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
12+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13+
*
14+
* @providesModule AnExApp
15+
* @flow
16+
*/
17+
'use strict';
18+
19+
var React = require('react-native');
20+
var {
21+
Animated,
22+
LayoutAnimation,
23+
PanResponder,
24+
StyleSheet,
25+
View,
26+
} = React;
27+
28+
var AnExSet = require('AnExSet');
29+
30+
var CIRCLE_SIZE = 80;
31+
var CIRCLE_MARGIN = 18;
32+
var NUM_CIRCLES = 30;
33+
34+
class Circle extends React.Component {
35+
_onLongPress: () => void;
36+
_toggleIsActive: () => void;
37+
constructor(props: Object): void {
38+
super();
39+
this._onLongPress = this._onLongPress.bind(this);
40+
this._toggleIsActive = this._toggleIsActive.bind(this);
41+
this.state = {isActive: false};
42+
this.state.pan = new Animated.ValueXY(); // Vectors reduce boilerplate. (step1: uncomment)
43+
this.state.pop = new Animated.Value(0); // Initial value. (step2a: uncomment)
44+
}
45+
46+
_onLongPress(): void {
47+
var config = {tension: 40, friction: 3};
48+
this.state.pan.addListener((value) => { // Async listener for state changes (step1: uncomment)
49+
this.props.onMove && this.props.onMove(value);
50+
});
51+
Animated.spring(this.state.pop, {
52+
toValue: 1, // Pop to larger size. (step2b: uncomment)
53+
...config, // Reuse config for convenient consistency (step2b: uncomment)
54+
}).start();
55+
this.setState({panResponder: PanResponder.create({
56+
onPanResponderMove: Animated.event([
57+
null, // native event - ignore (step1: uncomment)
58+
{dx: this.state.pan.x, dy: this.state.pan.y}, // links pan to gestureState (step1: uncomment)
59+
]),
60+
onPanResponderRelease: (e, gestureState) => {
61+
LayoutAnimation.easeInEaseOut(); // @flowfixme animates layout update as one batch (step3: uncomment)
62+
Animated.spring(this.state.pop, {
63+
toValue: 0, // Pop back to 0 (step2c: uncomment)
64+
...config,
65+
}).start();
66+
this.setState({panResponder: undefined});
67+
this.props.onMove && this.props.onMove({
68+
x: gestureState.dx + this.props.restLayout.x,
69+
y: gestureState.dy + this.props.restLayout.y,
70+
});
71+
this.props.onDeactivate();
72+
},
73+
})}, () => {
74+
this.props.onActivate();
75+
});
76+
}
77+
78+
render(): ReactElement {
79+
if (this.state.panResponder) {
80+
var handlers = this.state.panResponder.panHandlers;
81+
var dragStyle = { // Used to position while dragging
82+
position: 'absolute', // Hoist out of layout (step1: uncomment)
83+
...this.state.pan.getLayout(), // Convenience converter (step1: uncomment)
84+
};
85+
} else {
86+
handlers = {
87+
onStartShouldSetResponder: () => !this.state.isActive,
88+
onResponderGrant: () => {
89+
this.state.pan.setValue({x: 0, y: 0}); // reset (step1: uncomment)
90+
this.state.pan.setOffset(this.props.restLayout); // offset from onLayout (step1: uncomment)
91+
this.longTimer = setTimeout(this._onLongPress, 300);
92+
},
93+
onResponderRelease: () => {
94+
if (!this.state.panResponder) {
95+
clearTimeout(this.longTimer);
96+
this._toggleIsActive();
97+
}
98+
}
99+
};
100+
}
101+
var animatedStyle: Object = {
102+
shadowOpacity: this.state.pop, // no need for interpolation (step2d: uncomment)
103+
transform: [
104+
{scale: this.state.pop.interpolate({
105+
inputRange: [0, 1],
106+
outputRange: [1, 1.3] // scale up from 1 to 1.3 (step2d: uncomment)
107+
})},
108+
],
109+
};
110+
var openVal = this.props.openVal;
111+
if (this.props.dummy) {
112+
animatedStyle.opacity = 0;
113+
} else if (this.state.isActive) {
114+
var innerOpenStyle = [styles.open, { // (step4: uncomment)
115+
left: openVal.interpolate({inputRange: [0, 1], outputRange: [this.props.restLayout.x, 0]}),
116+
top: openVal.interpolate({inputRange: [0, 1], outputRange: [this.props.restLayout.y, 0]}),
117+
width: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_SIZE, this.props.containerLayout.width]}),
118+
height: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_SIZE, this.props.containerLayout.height]}),
119+
margin: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_MARGIN, 0]}),
120+
borderRadius: openVal.interpolate({inputRange: [-0.15, 0, 0.5, 1], outputRange: [0, CIRCLE_SIZE / 2, CIRCLE_SIZE * 1.3, 0]}),
121+
}];
122+
}
123+
return (
124+
<Animated.View
125+
onLayout={this.props.onLayout}
126+
style={[styles.dragView, dragStyle, animatedStyle, this.state.isActive ? styles.open : null]}
127+
{...handlers}>
128+
<Animated.View style={[styles.circle, innerOpenStyle]}>
129+
<AnExSet
130+
containerLayout={this.props.containerLayout}
131+
id={this.props.id}
132+
isActive={this.state.isActive}
133+
openVal={this.props.openVal}
134+
onDismiss={this._toggleIsActive}
135+
/>
136+
</Animated.View>
137+
</Animated.View>
138+
);
139+
}
140+
_toggleIsActive(velocity) {
141+
var config = {tension: 30, friction: 7};
142+
if (this.state.isActive) {
143+
Animated.spring(this.props.openVal, {toValue: 0, ...config}).start(() => { // (step4: uncomment)
144+
this.setState({isActive: false}, this.props.onDeactivate);
145+
}); // (step4: uncomment)
146+
} else {
147+
this.props.onActivate();
148+
this.setState({isActive: true, panResponder: undefined}, () => {
149+
// this.props.openVal.setValue(1); // (step4: comment)
150+
Animated.spring(this.props.openVal, {toValue: 1, ...config}).start(); // (step4: uncomment)
151+
});
152+
}
153+
}
154+
}
155+
156+
class AnExApp extends React.Component {
157+
_onMove: (position: Point) => void;
158+
constructor(props: any): void {
159+
super(props);
160+
var keys = [];
161+
for (var idx = 0; idx < NUM_CIRCLES; idx++) {
162+
keys.push('E' + idx);
163+
}
164+
this.state = {
165+
keys,
166+
restLayouts: [],
167+
openVal: new Animated.Value(0),
168+
};
169+
this._onMove = this._onMove.bind(this);
170+
}
171+
172+
render(): ReactElement {
173+
var circles = this.state.keys.map((key, idx) => {
174+
if (key === this.state.activeKey) {
175+
return <Circle key={key + 'd'} dummy={true} />;
176+
} else {
177+
if (!this.state.restLayouts[idx]) {
178+
var onLayout = function(index, e) {
179+
var layout = e.nativeEvent.layout;
180+
this.setState((state) => {
181+
state.restLayouts[index] = layout;
182+
return state;
183+
});
184+
}.bind(this, idx);
185+
}
186+
return (
187+
<Circle
188+
key={key}
189+
id={key}
190+
openVal={this.state.openVal}
191+
onLayout={onLayout}
192+
restLayout={this.state.restLayouts[idx]}
193+
onActivate={this.setState.bind(this, {
194+
activeKey: key,
195+
activeInitialLayout: this.state.restLayouts[idx],
196+
})}
197+
/>
198+
);
199+
}
200+
});
201+
if (this.state.activeKey) {
202+
circles.push(
203+
<Animated.View key="dark" style={[styles.darkening, {opacity: this.state.openVal}]} />
204+
);
205+
circles.push(
206+
<Circle
207+
openVal={this.state.openVal}
208+
key={this.state.activeKey}
209+
id={this.state.activeKey}
210+
restLayout={this.state.activeInitialLayout}
211+
containerLayout={this.state.layout}
212+
onMove={this._onMove}
213+
onDeactivate={() => { this.setState({activeKey: undefined}); }}
214+
/>
215+
);
216+
}
217+
return (
218+
<View style={styles.container}>
219+
<View style={styles.grid} onLayout={(e) => this.setState({layout: e.nativeEvent.layout})}>
220+
{circles}
221+
</View>
222+
</View>
223+
);
224+
}
225+
226+
_onMove(position: Point): void {
227+
var newKeys = moveToClosest(this.state, position);
228+
if (newKeys !== this.state.keys) {
229+
LayoutAnimation.easeInEaseOut(); // animates layout update as one batch (step3: uncomment)
230+
this.setState({keys: newKeys});
231+
}
232+
}
233+
}
234+
235+
type Point = {x: number, y: number};
236+
function distance(p1: Point, p2: Point): number {
237+
var dx = p1.x - p2.x;
238+
var dy = p1.y - p2.y;
239+
return dx * dx + dy * dy;
240+
}
241+
242+
function moveToClosest({activeKey, keys, restLayouts}, position) {
243+
var activeIdx = -1;
244+
var closestIdx = activeIdx;
245+
var minDist = Infinity;
246+
var newKeys = [];
247+
keys.forEach((key, idx) => {
248+
var dist = distance(position, restLayouts[idx]);
249+
if (key === activeKey) {
250+
idx = activeIdx;
251+
} else {
252+
newKeys.push(key);
253+
}
254+
if (dist < minDist) {
255+
minDist = dist;
256+
closestIdx = idx;
257+
}
258+
});
259+
if (closestIdx === activeIdx) {
260+
return keys; // nothing changed
261+
} else {
262+
newKeys.splice(closestIdx, 0, activeKey);
263+
return newKeys;
264+
}
265+
}
266+
267+
AnExApp.title = 'Animated - Gratuitous App';
268+
AnExApp.description = 'Bunch of Animations - tap a circle to ' +
269+
'open a view with more animations, or longPress and drag to reorder circles.';
270+
271+
var styles = StyleSheet.create({
272+
container: {
273+
flex: 1,
274+
paddingTop: 64, // push content below nav bar
275+
},
276+
grid: {
277+
flex: 1,
278+
justifyContent: 'center',
279+
flexDirection: 'row',
280+
flexWrap: 'wrap',
281+
backgroundColor: 'transparent',
282+
},
283+
circle: {
284+
width: CIRCLE_SIZE,
285+
height: CIRCLE_SIZE,
286+
borderRadius: CIRCLE_SIZE / 2,
287+
borderWidth: 1,
288+
borderColor: 'black',
289+
margin: CIRCLE_MARGIN,
290+
overflow: 'hidden',
291+
},
292+
dragView: {
293+
shadowRadius: 10,
294+
shadowColor: 'rgba(0,0,0,0.7)',
295+
shadowOffset: {height: 8},
296+
alignSelf: 'flex-start',
297+
backgroundColor: 'transparent',
298+
},
299+
open: {
300+
position: 'absolute',
301+
left: 0,
302+
top: 0,
303+
right: 0,
304+
bottom: 0,
305+
width: undefined, // unset value from styles.circle
306+
height: undefined, // unset value from styles.circle
307+
borderRadius: 0, // unset value from styles.circle
308+
},
309+
darkening: {
310+
backgroundColor: 'black',
311+
position: 'absolute',
312+
left: 0,
313+
top: 0,
314+
right: 0,
315+
bottom: 0,
316+
},
317+
});
318+
319+
module.exports = AnExApp;

0 commit comments

Comments
 (0)