/** * Copyright (c) 2015-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * @flow */ 'use strict'; const React = require('react'); const ReactNative = require('react-native'); const { View, Text, Animated, StyleSheet, TouchableWithoutFeedback, Slider, } = ReactNative; var AnimatedSlider = Animated.createAnimatedComponent(Slider); class Tester extends React.Component<$FlowFixMeProps, $FlowFixMeState> { state = { native: new Animated.Value(0), js: new Animated.Value(0), }; current = 0; onPress = () => { const animConfig = this.current && this.props.reverseConfig ? this.props.reverseConfig : this.props.config; this.current = this.current ? 0 : 1; const config: Object = { ...animConfig, toValue: this.current, }; Animated[this.props.type](this.state.native, { ...config, useNativeDriver: true, }).start(); Animated[this.props.type](this.state.js, { ...config, useNativeDriver: false, }).start(); }; render() { return ( Native: {this.props.children(this.state.native)} JavaScript: {this.props.children(this.state.js)} ); } } class ValueListenerExample extends React.Component<{}, $FlowFixMeState> { 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 ( Value: {this.state.progress} ); } } class LoopExample extends React.Component<{}, $FlowFixMeState> { state = { value: new Animated.Value(0), }; componentDidMount() { Animated.loop( Animated.timing(this.state.value, { toValue: 1, duration: 5000, useNativeDriver: true, }), ).start(); } render() { return ( ); } } const RNTesterSettingSwitchRow = require('RNTesterSettingSwitchRow'); class InternalSettings extends React.Component< {}, {busyTime: number | string, filteredStall: number}, > { _stallInterval: ?number; render() { return ( { /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment * suppresses an error found when Flow v0.63 was deployed. To see * the error delete this comment and run Flow. */ this._stallInterval = setInterval(() => { const start = Date.now(); console.warn('burn CPU'); while (Date.now() - start < 100) {} }, 300); }} onDisable={() => { /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment * suppresses an error found when Flow v0.63 was deployed. To see * the error delete this comment and run Flow. */ clearInterval(this._stallInterval || 0); }} /> { require('JSEventLoopWatchdog').install({thresholdMS: 25}); this.setState({busyTime: ''}); 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 && ( {`JS Stall filtered: ${Math.round(this.state.filteredStall)}, `} {`last: ${this.state.busyTime}`} )} ); } } class EventExample extends React.Component<{}, $FlowFixMeState> { state = { scrollX: new Animated.Value(0), }; render() { const opacity = this.state.scrollX.interpolate({ inputRange: [0, 200], outputRange: [1, 0], }); return ( Scroll me! ); } } class TrackingExample extends React.Component< $FlowFixMeProps, $FlowFixMeState, > { state = { native: new Animated.Value(0), toNative: new Animated.Value(0), js: new Animated.Value(0), toJS: new Animated.Value(0), }; componentDidMount() { // we configure spring to take a bit of time to settle so that the user // have time to click many times and see "toValue" getting updated and const longSettlingSpring = { tension: 20, friction: 0.5, }; Animated.spring(this.state.native, { ...longSettlingSpring, toValue: this.state.toNative, useNativeDriver: true, }).start(); Animated.spring(this.state.js, { ...longSettlingSpring, toValue: this.state.toJS, useNativeDriver: false, }).start(); } onPress = () => { // select next value to be tracked by random const nextValue = Math.random() * 200; this.state.toNative.setValue(nextValue); this.state.toJS.setValue(nextValue); }; renderBlock = (anim, dest) => [ , , ]; render() { return ( Native: {this.renderBlock(this.state.native, this.state.toNative)} JavaScript: {this.renderBlock(this.state.js, this.state.toJS)} ); } } const styles = StyleSheet.create({ row: { padding: 10, zIndex: 1, }, block: { width: 50, height: 50, backgroundColor: 'blue', }, line: { position: 'absolute', left: 35, top: 0, bottom: 0, width: 1, backgroundColor: 'red', }, }); 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 ( {anim => ( )} ); }, }, { title: 'Multistage With Multiply', render: function() { return ( {anim => ( )} ); }, }, { title: 'Multistage With Subtract', render: function() { return ( {anim => ( )} ); }, }, { title: 'Scale interpolation with clamping', render: function() { return ( {anim => ( )} ); }, }, { title: 'Opacity with delay', render: function() { return ( {anim => ( )} ); }, }, { title: 'Rotate interpolation', render: function() { return ( {anim => ( )} ); }, }, { title: 'translateX => Animated.spring (bounciness/speed)', render: function() { return ( {anim => ( )} ); }, }, { title: 'translateX => Animated.spring (stiffness/damping/mass)', render: function() { return ( {anim => ( )} ); }, }, { title: 'translateX => Animated.decay', render: function() { return ( {anim => ( )} ); }, }, { title: 'Drive custom property', render: function() { return ( {anim => } ); }, }, { title: 'Animated value listener', render: function() { return ; }, }, { title: 'Animated loop', render: function() { return ; }, }, { title: 'Animated events', render: function() { return ; }, }, { title: 'Animated Tracking - tap me many times', render: function() { return ; }, }, { title: 'Internal Settings', render: function() { return ; }, }, ];