2016-06-09 17:34:41 +00:00
|
|
|
/**
|
2017-05-06 03:50:47 +00:00
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
2016-06-09 17:34:41 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
* @flow
|
2017-02-25 11:05:32 +00:00
|
|
|
* @providesModule NativeAnimationsExample
|
2016-06-09 17:34:41 +00:00
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2016-08-04 20:11:37 +00:00
|
|
|
const React = require('react');
|
|
|
|
const ReactNative = require('react-native');
|
|
|
|
const {
|
2016-06-09 17:34:41 +00:00
|
|
|
View,
|
|
|
|
Text,
|
|
|
|
Animated,
|
|
|
|
StyleSheet,
|
|
|
|
TouchableWithoutFeedback,
|
2017-01-27 02:14:40 +00:00
|
|
|
Slider,
|
2016-06-09 17:34:41 +00:00
|
|
|
} = ReactNative;
|
|
|
|
|
2017-01-27 02:14:40 +00:00
|
|
|
var AnimatedSlider = Animated.createAnimatedComponent(Slider);
|
|
|
|
|
2016-07-26 08:00:02 +00:00
|
|
|
class Tester extends React.Component {
|
|
|
|
state = {
|
|
|
|
native: new Animated.Value(0),
|
|
|
|
js: new Animated.Value(0),
|
|
|
|
};
|
|
|
|
|
|
|
|
current = 0;
|
2016-06-09 17:34:41 +00:00
|
|
|
|
2016-07-26 08:00:02 +00:00
|
|
|
onPress = () => {
|
2016-08-19 14:06:29 +00:00
|
|
|
const animConfig = (
|
|
|
|
this.current && this.props.reverseConfig ? this.props.reverseConfig : this.props.config
|
|
|
|
);
|
2016-06-09 17:34:41 +00:00
|
|
|
this.current = this.current ? 0 : 1;
|
2017-04-05 17:16:30 +00:00
|
|
|
const config: Object = {
|
2016-08-19 14:06:29 +00:00
|
|
|
...animConfig,
|
2016-06-09 17:34:41 +00:00
|
|
|
toValue: this.current,
|
|
|
|
};
|
2016-08-04 20:11:37 +00:00
|
|
|
|
|
|
|
Animated[this.props.type](this.state.native, { ...config, useNativeDriver: true }).start();
|
2016-06-09 17:34:41 +00:00
|
|
|
Animated[this.props.type](this.state.js, { ...config, useNativeDriver: false }).start();
|
2016-07-26 08:00:02 +00:00
|
|
|
};
|
2016-06-09 17:34:41 +00:00
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<TouchableWithoutFeedback onPress={this.onPress}>
|
|
|
|
<View>
|
|
|
|
<View>
|
|
|
|
<Text>Native:</Text>
|
|
|
|
</View>
|
|
|
|
<View style={styles.row}>
|
|
|
|
{this.props.children(this.state.native)}
|
|
|
|
</View>
|
|
|
|
<View>
|
|
|
|
<Text>JavaScript:</Text>
|
|
|
|
</View>
|
|
|
|
<View style={styles.row}>
|
|
|
|
{this.props.children(this.state.js)}
|
|
|
|
</View>
|
|
|
|
</View>
|
|
|
|
</TouchableWithoutFeedback>
|
|
|
|
);
|
2016-07-26 08:00:02 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-09 17:34:41 +00:00
|
|
|
|
2016-08-04 20:11:37 +00:00
|
|
|
class ValueListenerExample extends React.Component {
|
|
|
|
state = {
|
|
|
|
anim: new Animated.Value(0),
|
|
|
|
progress: 0,
|
|
|
|
};
|
|
|
|
_current = 0;
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
this.state.anim.addListener((e) => this.setState({ progress: e.value }));
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.state.anim.removeAllListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
_onPress = () => {
|
|
|
|
this._current = this._current ? 0 : 1;
|
|
|
|
const config = {
|
|
|
|
duration: 1000,
|
|
|
|
toValue: this._current,
|
|
|
|
};
|
|
|
|
|
|
|
|
Animated.timing(this.state.anim, { ...config, useNativeDriver: true }).start();
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<TouchableWithoutFeedback onPress={this._onPress}>
|
|
|
|
<View>
|
|
|
|
<View style={styles.row}>
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
opacity: this.state.anim,
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
</View>
|
|
|
|
<Text>Value: {this.state.progress}</Text>
|
|
|
|
</View>
|
|
|
|
</TouchableWithoutFeedback>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-06 03:50:47 +00:00
|
|
|
const RNTesterSettingSwitchRow = require('RNTesterSettingSwitchRow');
|
2016-09-07 02:45:08 +00:00
|
|
|
class InternalSettings extends React.Component {
|
|
|
|
_stallInterval: ?number;
|
|
|
|
state: {busyTime: number | string, filteredStall: number};
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<View>
|
2017-05-06 03:50:47 +00:00
|
|
|
<RNTesterSettingSwitchRow
|
2016-09-07 02:45:08 +00:00
|
|
|
initialValue={false}
|
|
|
|
label="Force JS Stalls"
|
|
|
|
onEnable={() => {
|
|
|
|
this._stallInterval = setInterval(() => {
|
|
|
|
const start = Date.now();
|
|
|
|
console.warn('burn CPU');
|
|
|
|
while ((Date.now() - start) < 100) {}
|
|
|
|
}, 300);
|
|
|
|
}}
|
|
|
|
onDisable={() => {
|
|
|
|
clearInterval(this._stallInterval || 0);
|
|
|
|
}}
|
|
|
|
/>
|
2017-05-06 03:50:47 +00:00
|
|
|
<RNTesterSettingSwitchRow
|
2016-09-07 02:45:08 +00:00
|
|
|
initialValue={false}
|
|
|
|
label="Track JS Stalls"
|
|
|
|
onEnable={() => {
|
|
|
|
require('JSEventLoopWatchdog').install({thresholdMS: 25});
|
|
|
|
this.setState({busyTime: '<none>'});
|
|
|
|
require('JSEventLoopWatchdog').addHandler({
|
|
|
|
onStall: ({busyTime}) => this.setState((state) => ({
|
|
|
|
busyTime,
|
|
|
|
filteredStall: (state.filteredStall || 0) * 0.97 + busyTime * 0.03,
|
|
|
|
})),
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
onDisable={() => {
|
|
|
|
console.warn('Cannot disable yet....');
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
{this.state && <Text>
|
|
|
|
JS Stall filtered: {Math.round(this.state.filteredStall)}, last: {this.state.busyTime}
|
|
|
|
</Text>}
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-19 11:07:36 +00:00
|
|
|
class EventExample extends React.Component {
|
|
|
|
state = {
|
|
|
|
scrollX: new Animated.Value(0),
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const opacity = this.state.scrollX.interpolate({
|
|
|
|
inputRange: [0, 200],
|
|
|
|
outputRange: [1, 0],
|
|
|
|
});
|
|
|
|
return (
|
|
|
|
<View>
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
opacity,
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
<Animated.ScrollView
|
|
|
|
horizontal
|
|
|
|
style={{ height: 100, marginTop: 16 }}
|
2016-11-01 10:56:50 +00:00
|
|
|
scrollEventThrottle={16}
|
2016-09-19 11:07:36 +00:00
|
|
|
onScroll={
|
|
|
|
Animated.event([{
|
|
|
|
nativeEvent: { contentOffset: { x: this.state.scrollX } }
|
|
|
|
}], {
|
|
|
|
useNativeDriver: true,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<View style={{ width: 600, backgroundColor: '#eee', justifyContent: 'center' }}>
|
|
|
|
<Text>Scroll me!</Text>
|
|
|
|
</View>
|
|
|
|
</Animated.ScrollView>
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-09 17:34:41 +00:00
|
|
|
const styles = StyleSheet.create({
|
|
|
|
row: {
|
|
|
|
padding: 10,
|
|
|
|
zIndex: 1,
|
|
|
|
},
|
|
|
|
block: {
|
|
|
|
width: 50,
|
|
|
|
height: 50,
|
|
|
|
backgroundColor: 'blue',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
exports.framework = 'React';
|
|
|
|
exports.title = 'Native Animated Example';
|
|
|
|
exports.description = 'Test out Native Animations';
|
|
|
|
|
|
|
|
exports.examples = [
|
|
|
|
{
|
|
|
|
title: 'Multistage With Multiply and rotation',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="timing"
|
2016-09-07 02:45:08 +00:00
|
|
|
config={{ duration: 1000 }}>
|
2016-06-09 17:34:41 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
transform: [
|
|
|
|
{
|
|
|
|
translateX: anim.interpolate({
|
|
|
|
inputRange: [0, 1],
|
|
|
|
outputRange: [0, 200],
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
translateY: anim.interpolate({
|
|
|
|
inputRange: [0, 0.5, 1],
|
|
|
|
outputRange: [0, 50, 0],
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
rotate: anim.interpolate({
|
|
|
|
inputRange: [0, 0.5, 1],
|
|
|
|
outputRange: ['0deg', '90deg', '0deg'],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
],
|
|
|
|
opacity: Animated.multiply(
|
|
|
|
anim.interpolate({
|
|
|
|
inputRange: [0,1],
|
|
|
|
outputRange: [1,0]
|
|
|
|
}), anim.interpolate({
|
|
|
|
inputRange: [0,1],
|
|
|
|
outputRange: [0.25,1]
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'Multistage With Multiply',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="timing"
|
2016-09-07 02:45:08 +00:00
|
|
|
config={{ duration: 1000 }}>
|
2016-06-09 17:34:41 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
transform: [
|
|
|
|
{
|
|
|
|
translateX: anim.interpolate({
|
|
|
|
inputRange: [0, 1],
|
|
|
|
outputRange: [0, 200],
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
translateY: anim.interpolate({
|
|
|
|
inputRange: [0, 0.5, 1],
|
|
|
|
outputRange: [0, 50, 0],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
],
|
|
|
|
opacity: Animated.multiply(
|
|
|
|
anim.interpolate({
|
|
|
|
inputRange: [0,1],
|
|
|
|
outputRange: [1,0]
|
|
|
|
}), anim.interpolate({
|
|
|
|
inputRange: [0,1],
|
|
|
|
outputRange: [0.25,1]
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-10-20 21:12:37 +00:00
|
|
|
title: 'Scale interpolation with clamping',
|
2016-06-09 17:34:41 +00:00
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="timing"
|
2016-09-07 02:45:08 +00:00
|
|
|
config={{ duration: 1000 }}>
|
2016-06-09 17:34:41 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
transform: [
|
|
|
|
{
|
|
|
|
scale: anim.interpolate({
|
2016-10-20 21:12:37 +00:00
|
|
|
inputRange: [0, 0.5],
|
2016-06-09 17:34:41 +00:00
|
|
|
outputRange: [1, 1.4],
|
2016-10-20 21:12:37 +00:00
|
|
|
extrapolateRight: 'clamp',
|
2016-06-09 17:34:41 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2017-03-28 16:08:49 +00:00
|
|
|
title: 'Opacity with delay',
|
2016-06-09 17:34:41 +00:00
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="timing"
|
2017-03-28 16:08:49 +00:00
|
|
|
config={{ duration: 1000, delay: 1000 }}>
|
2016-06-09 17:34:41 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
opacity: anim
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'Rotate interpolation',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="timing"
|
2016-09-07 02:45:08 +00:00
|
|
|
config={{ duration: 1000 }}>
|
2016-06-09 17:34:41 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
transform: [
|
|
|
|
{
|
|
|
|
rotate: anim.interpolate({
|
|
|
|
inputRange: [0, 1],
|
|
|
|
outputRange: ['0deg', '90deg'],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'translateX => Animated.spring',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="spring"
|
2016-09-07 02:45:08 +00:00
|
|
|
config={{ bounciness: 0 }}>
|
2016-06-09 17:34:41 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
transform: [
|
|
|
|
{
|
|
|
|
translateX: anim.interpolate({
|
|
|
|
inputRange: [0, 1],
|
|
|
|
outputRange: [0, 100],
|
|
|
|
})
|
2016-08-07 07:44:09 +00:00
|
|
|
},
|
2016-06-09 17:34:41 +00:00
|
|
|
],
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
2016-08-19 14:06:29 +00:00
|
|
|
},{
|
|
|
|
title: 'translateX => Animated.decay',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="decay"
|
|
|
|
config={{ velocity: 0.5 }}
|
2016-09-07 02:45:08 +00:00
|
|
|
reverseConfig={{ velocity: -0.5 }}>
|
2016-08-19 14:06:29 +00:00
|
|
|
{anim => (
|
|
|
|
<Animated.View
|
|
|
|
style={[
|
|
|
|
styles.block,
|
|
|
|
{
|
|
|
|
transform: [
|
|
|
|
{
|
|
|
|
translateX: anim
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
2017-01-27 02:14:40 +00:00
|
|
|
},{
|
|
|
|
title: 'Drive custom property',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<Tester
|
|
|
|
type="timing"
|
|
|
|
config={{ duration: 1000 }}>
|
|
|
|
{anim => (
|
|
|
|
<AnimatedSlider style={{}} value={anim} />
|
|
|
|
)}
|
|
|
|
</Tester>
|
|
|
|
);
|
|
|
|
},
|
2016-06-09 17:34:41 +00:00
|
|
|
},
|
2016-08-04 20:11:37 +00:00
|
|
|
{
|
|
|
|
title: 'Animated value listener',
|
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<ValueListenerExample />
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
2016-09-07 02:45:08 +00:00
|
|
|
{
|
2016-11-01 10:56:50 +00:00
|
|
|
title: 'Animated events',
|
2016-09-07 02:45:08 +00:00
|
|
|
render: function() {
|
|
|
|
return (
|
2016-11-01 10:56:50 +00:00
|
|
|
<EventExample />
|
2016-09-07 02:45:08 +00:00
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
2016-09-19 11:07:36 +00:00
|
|
|
{
|
2016-11-01 10:56:50 +00:00
|
|
|
title: 'Internal Settings',
|
2016-09-19 11:07:36 +00:00
|
|
|
render: function() {
|
|
|
|
return (
|
2016-11-01 10:56:50 +00:00
|
|
|
<InternalSettings />
|
2016-09-19 11:07:36 +00:00
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
2016-06-09 17:34:41 +00:00
|
|
|
];
|