mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
45bbb2c3a1
Deploy website version based on c498d640f5
456 lines
68 KiB
HTML
456 lines
68 KiB
HTML
<html><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/><title>Animations · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta property="og:title" content="Animations · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="Animations are very important to create a great user experience."/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/blog/feed.xml" title="React Native Blog RSS Feed"/><script type="text/javascript" src="https://snack.expo.io/embed.js"></script><script type="text/javascript" src="/react-native/js/codeblocks.js"></script><link rel="stylesheet" href="/react-native/css/main.css"/></head><body class="sideNavVisible"><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/react-native/"><img class="logo" src="/react-native/img/header_logo.png"/><h2 class="headerTitle">React Native</h2></a><a href="/react-native/versions.html"><h3>0.51</h3></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li><a href="/react-native/docs/getting-started.html" target="_self">Docs</a></li><li><a href="/react-native/en/help.html" target="_self">Community</a></li><li><a href="/react-native/blog" target="_self">Blog</a></li><li class="navSearchWrapper reactNavSearchWrapper"><input type="text" id="search_input_react" placeholder="Search"/></li><li><a href="https://github.com/facebook/react-native" target="_self">GitHub</a></li><li><a href="https://reactjs.org/" target="_self">React</a></li></ul></nav></div></header></div></div><div class="navPusher"><div class="docMainWrapper wrapper"><div class="container docsNavContainer" id="docsNav"><nav class="toc"><div class="toggleNav"><section class="navWrapper wrapper"><div class="navBreadcrumb wrapper"><div class="navToggle" id="navToggler"><i></i></div><h2><i>›</i><span>Guides</span></h2></div><div class="navGroups"><div class="navGroup navGroupActive"><h3>The Basics</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/getting-started.html">Getting Started</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/tutorial.html">Learn the Basics</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/props.html">Props</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/state.html">State</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/style.html">Style</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/height-and-width.html">Height and Width</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/flexbox.html">Layout with Flexbox</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/handling-text-input.html">Handling Text Input</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/handling-touches.html">Handling Touches</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/using-a-scrollview.html">Using a ScrollView</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/using-a-listview.html">Using List Views</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/network.html">Networking</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/more-resources.html">More Resources</a></li></ul></div><div class="navGroup navGroupActive"><h3>Guides</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/components-and-apis.html">Components and APIs</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/platform-specific-code.html">Platform Specific Code</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/navigation.html">Navigating Between Screens</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/images.html">Images</a></li><li class="navListItem navListItemActive"><a class="navItem navItemActive" href="/react-native/docs/animations.html">Animations</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/accessibility.html">Accessibility</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/improvingux.html">Improving User Experience</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/timers.html">Timers</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/debugging.html">Debugging</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/performance.html">Performance</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/gesture-responder-system.html">Gesture Responder System</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/javascript-environment.html">JavaScript Environment</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/direct-manipulation.html">Direct Manipulation</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/colors.html">Color Reference</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/integration-with-existing-apps.html">Integration with Existing Apps</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/running-on-device.html">Running On Device</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/upgrading.html">Upgrading to new React Native versions</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/troubleshooting.html">Troubleshooting</a></li></ul></div><div class="navGroup navGroupActive"><h3>Guides (iOS)</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/native-modules-ios.html">Native Modules</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/native-components-ios.html">Native UI Components</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/linking-libraries-ios.html">Linking Libraries</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/running-on-simulator-ios.html">Running On Simulator</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/communication-ios.html">Communication between native and React Native</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/building-for-apple-tv.html">Building For Apple TV</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/app-extensions.html">App Extensions</a></li></ul></div><div class="navGroup navGroupActive"><h3>Guides (Android)</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/native-modules-android.html">Native Modules</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/native-components-android.html">Native UI Components</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/headless-js-android.html">Headless JS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/signed-apk-android.html">Generating Signed APK</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/android-building-from-source.html">Building React Native from source</a></li></ul></div><div class="navGroup navGroupActive"><h3>Contributing</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/contributing.html">How to Contribute</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/maintainers.html">What to Expect from Maintainers</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/testing.html">Testing your Changes</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/understanding-cli.html">Understanding the CLI</a></li></ul></div><div class="navGroup navGroupActive"><h3>Components</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/activityindicator.html">ActivityIndicator</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/button.html">Button</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/datepickerios.html">DatePickerIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/drawerlayoutandroid.html">DrawerLayoutAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/flatlist.html">FlatList</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/image.html">Image</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/keyboardavoidingview.html">KeyboardAvoidingView</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/listview.html">ListView</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/maskedviewios.html">MaskedViewIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/modal.html">Modal</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/navigatorios.html">NavigatorIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/picker.html">Picker</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/pickerios.html">PickerIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/progressbarandroid.html">ProgressBarAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/progressviewios.html">ProgressViewIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/refreshcontrol.html">RefreshControl</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/scrollview.html">ScrollView</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/sectionlist.html">SectionList</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/segmentedcontrolios.html">SegmentedControlIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/slider.html">Slider</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/snapshotviewios.html">SnapshotViewIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/statusbar.html">StatusBar</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/switch.html">Switch</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/tabbarios.html">TabBarIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/tabbarios-item.html">TabBarIOS.Item</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/text.html">Text</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/textinput.html">TextInput</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/toolbarandroid.html">ToolbarAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/touchablehighlight.html">TouchableHighlight</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/touchablenativefeedback.html">TouchableNativeFeedback</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/touchableopacity.html">TouchableOpacity</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/touchablewithoutfeedback.html">TouchableWithoutFeedback</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/view.html">View</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/viewpagerandroid.html">ViewPagerAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/virtualizedlist.html">VirtualizedList</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/webview.html">WebView</a></li></ul></div><div class="navGroup navGroupActive"><h3>APIs</h3><ul><li class="navListItem"><a class="navItem" href="/react-native/docs/accessibilityinfo.html">AccessibilityInfo</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/actionsheetios.html">ActionSheetIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/alert.html">Alert</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/alertios.html">AlertIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/animated.html">Animated</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/appregistry.html">AppRegistry</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/appstate.html">AppState</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/asyncstorage.html">AsyncStorage</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/backandroid.html">BackAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/backhandler.html">BackHandler</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/cameraroll.html">CameraRoll</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/clipboard.html">Clipboard</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/datepickerandroid.html">DatePickerAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/dimensions.html">Dimensions</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/easing.html">Easing</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/geolocation.html">Geolocation</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/imageeditor.html">ImageEditor</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/imagepickerios.html">ImagePickerIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/imagestore.html">ImageStore</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/image-style-props.html">Image Style Props</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/interactionmanager.html">InteractionManager</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/keyboard.html">Keyboard</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/layout-props.html">Layout Props</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/layoutanimation.html">LayoutAnimation</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/linking.html">Linking</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/listviewdatasource.html">ListViewDataSource</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/netinfo.html">NetInfo</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/panresponder.html">PanResponder</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/permissionsandroid.html">PermissionsAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/pixelratio.html">PixelRatio</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/pushnotificationios.html">PushNotificationIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/settings.html">Settings</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/shadow-props.html">Shadow Props</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/share.html">Share</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/statusbarios.html">StatusBarIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/stylesheet.html">StyleSheet</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/systrace.html">Systrace</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/text-style-props.html">Text Style Props</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/timepickerandroid.html">TimePickerAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/toastandroid.html">ToastAndroid</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/transforms.html">Transforms</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/vibration.html">Vibration</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/vibrationios.html">VibrationIOS</a></li><li class="navListItem"><a class="navItem" href="/react-native/docs/view-style-props.html">View Style Props</a></li></ul></div></div></section></div><script>
|
||
var toggler = document.getElementById('navToggler');
|
||
var nav = document.getElementById('docsNav');
|
||
toggler.onclick = function() {
|
||
nav.classList.toggle('docsSliderActive');
|
||
};
|
||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/website/versioned_docs/version-0.5/animations.md" target="_blank">Edit</a><h1>Animations</h1></header><article><div><span><p>Animations are very important to create a great user experience.
|
||
Stationary objects must overcome inertia as they start moving.
|
||
Objects in motion have momentum and rarely come to a stop immediately.
|
||
Animations allow you to convey physically believable motion in your interface.</p>
|
||
<p>React Native provides two complementary animation systems:
|
||
<a href="/react-native/docs/animations.html#animated-api"><code>Animated</code></a> for granular and interactive control of specific values, and
|
||
<a href="/react-native/docs/animations.html#layoutanimation"><code>LayoutAnimation</code></a> for animated global layout transactions.</p>
|
||
<h2><a class="anchor" aria-hidden="true" name="animated-api"></a><a href="#animated-api" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>Animated</code> API</h2>
|
||
<p>The <a href="/react-native/docs/animated.html"><code>Animated</code></a> API is designed to make it very easy to concisely express a wide variety of interesting animation and interaction patterns in a very performant way.
|
||
<code>Animated</code> focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and simple <code>start</code>/<code>stop</code> methods to control time-based animation execution.</p>
|
||
<p><code>Animated</code> exports four animatable component types: <code>View</code>, <code>Text</code>, <code>Image</code>, and <code>ScrollView</code>, but you can also create your own using <code>Animated.createAnimatedComponent()</code>.</p>
|
||
<p>For example, a container view that fades in when it is mounted may look like this:</p>
|
||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||
<span class="hljs-keyword">import</span> { Animated, Text, View } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FadeInView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
|
||
state = {
|
||
<span class="hljs-attr">fadeAnim</span>: <span class="hljs-keyword">new</span> Animated.Value(<span class="hljs-number">0</span>), <span class="hljs-comment">// Initial value for opacity: 0</span>
|
||
}
|
||
|
||
componentDidMount() {
|
||
Animated.timing( <span class="hljs-comment">// Animate over time</span>
|
||
<span class="hljs-keyword">this</span>.state.fadeAnim, <span class="hljs-comment">// The animated value to drive</span>
|
||
{
|
||
<span class="hljs-attr">toValue</span>: <span class="hljs-number">1</span>, <span class="hljs-comment">// Animate to opacity: 1 (opaque)</span>
|
||
duration: <span class="hljs-number">10000</span>, <span class="hljs-comment">// Make it take a while</span>
|
||
}
|
||
).start(); <span class="hljs-comment">// Starts the animation</span>
|
||
}
|
||
|
||
render() {
|
||
<span class="hljs-keyword">let</span> { fadeAnim } = <span class="hljs-keyword">this</span>.state;
|
||
|
||
<span class="hljs-keyword">return</span> (
|
||
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Animated.View</span> // <span class="hljs-attr">Special</span> <span class="hljs-attr">animatable</span> <span class="hljs-attr">View</span>
|
||
<span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
|
||
<span class="hljs-attr">...this.props.style</span>,
|
||
<span class="hljs-attr">opacity:</span> <span class="hljs-attr">fadeAnim</span>, // <span class="hljs-attr">Bind</span> <span class="hljs-attr">opacity</span> <span class="hljs-attr">to</span> <span class="hljs-attr">animated</span> <span class="hljs-attr">value</span>
|
||
}}
|
||
></span>
|
||
{this.props.children}
|
||
<span class="hljs-tag"></<span class="hljs-name">Animated.View</span>></span>
|
||
);
|
||
}
|
||
}
|
||
|
||
// You can then use your `FadeInView` in place of a `View` in your components:
|
||
export default class App extends React.Component {
|
||
render() {
|
||
return (
|
||
<span class="hljs-tag"><<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{flex:</span> <span class="hljs-attr">1</span>, <span class="hljs-attr">alignItems:</span> '<span class="hljs-attr">center</span>', <span class="hljs-attr">justifyContent:</span> '<span class="hljs-attr">center</span>'}}></span>
|
||
<span class="hljs-tag"><<span class="hljs-name">FadeInView</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{width:</span> <span class="hljs-attr">250</span>, <span class="hljs-attr">height:</span> <span class="hljs-attr">50</span>, <span class="hljs-attr">backgroundColor:</span> '<span class="hljs-attr">powderblue</span>'}}></span>
|
||
<span class="hljs-tag"><<span class="hljs-name">Text</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{fontSize:</span> <span class="hljs-attr">28</span>, <span class="hljs-attr">textAlign:</span> '<span class="hljs-attr">center</span>', <span class="hljs-attr">margin:</span> <span class="hljs-attr">10</span>}}></span>Fading in<span class="hljs-tag"></<span class="hljs-name">Text</span>></span>
|
||
<span class="hljs-tag"></<span class="hljs-name">FadeInView</span>></span>
|
||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||
)
|
||
}
|
||
}
|
||
</span></code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||
data-snack-name="Example"
|
||
data-snack-description="Example usage"
|
||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20Animated%2C%20Text%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aclass%20FadeInView%20extends%20React.Component%20%7B%0A%20%20state%20%3D%20%7B%0A%20%20%20%20fadeAnim%3A%20new%20Animated.Value(0)%2C%20%20%2F%2F%20Initial%20value%20for%20opacity%3A%200%0A%20%20%7D%0A%0A%20%20componentDidMount()%20%7B%0A%20%20%20%20Animated.timing(%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Animate%20over%20time%0A%20%20%20%20%20%20this.state.fadeAnim%2C%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20The%20animated%20value%20to%20drive%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20toValue%3A%201%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Animate%20to%20opacity%3A%201%20(opaque)%0A%20%20%20%20%20%20%20%20duration%3A%2010000%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Make%20it%20take%20a%20while%0A%20%20%20%20%20%20%7D%0A%20%20%20%20).start()%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Starts%20the%20animation%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20let%20%7B%20fadeAnim%20%7D%20%3D%20this.state%3B%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CAnimated.View%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Special%20animatable%20View%0A%20%20%20%20%20%20%20%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20%20%20...this.props.style%2C%0A%20%20%20%20%20%20%20%20%20%20opacity%3A%20fadeAnim%2C%20%20%20%20%20%20%20%20%20%2F%2F%20Bind%20opacity%20to%20animated%20value%0A%20%20%20%20%20%20%20%20%7D%7D%0A%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%7Bthis.props.children%7D%0A%20%20%20%20%20%20%3C%2FAnimated.View%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0A%2F%2F%20You%20can%20then%20use%20your%20%60FadeInView%60%20in%20place%20of%20a%20%60View%60%20in%20your%20components%3A%0Aexport%20default%20class%20App%20extends%20React.Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20alignItems%3A%20'center'%2C%20justifyContent%3A%20'center'%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFadeInView%20style%3D%7B%7Bwidth%3A%20250%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7B%7BfontSize%3A%2028%2C%20textAlign%3A%20'center'%2C%20margin%3A%2010%7D%7D%3EFading%20in%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%3C%2FFadeInView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%0A%20%20%7D%0A%7D%0A"
|
||
data-snack-platform="ios"
|
||
data-snack-preview="true"
|
||
data-snack-sdk-version="23.0.0"
|
||
style="
|
||
overflow: hidden;
|
||
background: #fafafa;
|
||
border: 1px solid rgba(0,0,0,.16);
|
||
border-radius: 4px;
|
||
height: 514px;
|
||
width: 880px;
|
||
"
|
||
></div></div></div><p>Let's break down what's happening here.
|
||
In the <code>FadeInView</code> constructor, a new <code>Animated.Value</code> called <code>fadeAnim</code> is initialized as part of <code>state</code>.
|
||
The opacity property on the <code>View</code> is mapped to this animated value.
|
||
Behind the scenes, the numeric value is extracted and used to set opacity.</p>
|
||
<p>When the component mounts, the opacity is set to 0.
|
||
Then, an easing animation is started on the <code>fadeAnim</code> animated value,
|
||
which will update all of its dependent mappings (in this case, just the opacity) on each frame as the value animates to the final value of 1.</p>
|
||
<p>This is done in an optimized way that is faster than calling <code>setState</code> and re-rendering.<br>
|
||
Because the entire configuration is declarative, we will be able to implement further optimizations that serialize the configuration and runs the animation on a high-priority thread.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="configuring-animations"></a><a href="#configuring-animations" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configuring animations</h3>
|
||
<p>Animations are heavily configurable. Custom and predefined easing functions, delays, durations, decay factors, spring constants, and more can all be tweaked depending on the type of animation.</p>
|
||
<p><code>Animated</code> provides several animation types, the most commonly used one being <a href="/react-native/docs/animated.html#timing"><code>Animated.timing()</code></a>.
|
||
It supports animating a value over time using one of various predefined easing functions, or you can use your own.
|
||
Easing functions are typically used in animation to convey gradual acceleration and deceleration of objects.</p>
|
||
<p>By default, <code>timing</code> will use a easeInOut curve that conveys gradual acceleration to full speed and concludes by gradually decelerating to a stop.
|
||
You can specify a different easing function by passing a <code>easing</code> parameter.
|
||
Custom <code>duration</code> or even a <code>delay</code> before the animation starts is also supported.</p>
|
||
<p>For example, if we want to create a 2-second long animation of an object that slightly backs up before moving to its final position:</p>
|
||
<pre><code class="hljs css javascript">Animated.timing(
|
||
<span class="hljs-keyword">this</span>.state.xPosition,
|
||
{
|
||
<span class="hljs-attr">toValue</span>: <span class="hljs-number">100</span>,
|
||
<span class="hljs-attr">easing</span>: Easing.back(),
|
||
<span class="hljs-attr">duration</span>: <span class="hljs-number">2000</span>,
|
||
}
|
||
).start();
|
||
</code></pre>
|
||
<p>Take a look at the <a href="/react-native/docs/animated.html#configuring-animations">Configuring animations</a> section of the <code>Animated</code> API reference to learn more about all the config parameters supported by the built-in animations.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="composing-animations"></a><a href="#composing-animations" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composing animations</h3>
|
||
<p>Animations can be combined and played in sequence or in parallel.
|
||
Sequential animations can play immediately after the previous animation has finished,
|
||
or they can start after a specified delay.
|
||
The <code>Animated</code> API provides several methods, such as <code>sequence()</code> and <code>delay()</code>,
|
||
each of which simply take an array of animations to execute and automatically calls <code>start()</code>/<code>stop()</code> as needed.</p>
|
||
<p>For example, the following animation coasts to a stop, then it springs back while twirling in parallel:</p>
|
||
<pre><code class="hljs css javascript">Animated.sequence([ <span class="hljs-comment">// decay, then spring to start and twirl</span>
|
||
Animated.decay(position, { <span class="hljs-comment">// coast to a stop</span>
|
||
velocity: {<span class="hljs-attr">x</span>: gestureState.vx, <span class="hljs-attr">y</span>: gestureState.vy}, <span class="hljs-comment">// velocity from gesture release</span>
|
||
deceleration: <span class="hljs-number">0.997</span>,
|
||
}),
|
||
Animated.parallel([ <span class="hljs-comment">// after decay, in parallel:</span>
|
||
Animated.spring(position, {
|
||
<span class="hljs-attr">toValue</span>: {<span class="hljs-attr">x</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">0</span>} <span class="hljs-comment">// return to start</span>
|
||
}),
|
||
Animated.timing(twirl, { <span class="hljs-comment">// and twirl</span>
|
||
toValue: <span class="hljs-number">360</span>,
|
||
}),
|
||
]),
|
||
]).start(); <span class="hljs-comment">// start the sequence group</span>
|
||
</code></pre>
|
||
<p>If one animation is stopped or interrupted, then all other animations in the group are also stopped.
|
||
<code>Animated.parallel</code> has a <code>stopTogether</code> option that can be set to <code>false</code> to disable this.</p>
|
||
<p>You can find a full list of composition methods in the <a href="/react-native/docs/animated.html#composing-animations">Composing animations</a> section of the <code>Animated</code> API reference.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="combining-animated-values"></a><a href="#combining-animated-values" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Combining animated values</h3>
|
||
<p>You can <a href="/react-native/docs/animated.html#combining-animated-values">combine two animated values</a> via addition, multiplication, division, or modulo to make a new animated value.</p>
|
||
<p>There are some cases where an animated value needs to invert another animated value for calculation.
|
||
An example is inverting a scale (2x --> 0.5x):</p>
|
||
<pre><code class="hljs css javascript"><span class="hljs-keyword">const</span> a = <span class="hljs-keyword">new</span> Animated.Value(<span class="hljs-number">1</span>);
|
||
<span class="hljs-keyword">const</span> b = Animated.divide(<span class="hljs-number">1</span>, a);
|
||
|
||
Animated.spring(a, {
|
||
<span class="hljs-attr">toValue</span>: <span class="hljs-number">2</span>,
|
||
}).start();
|
||
</code></pre>
|
||
<h3><a class="anchor" aria-hidden="true" name="interpolation"></a><a href="#interpolation" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Interpolation</h3>
|
||
<p>Each property can be run through an interpolation first.
|
||
An interpolation maps input ranges to output ranges,
|
||
typically using a linear interpolation but also supports easing functions.
|
||
By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.</p>
|
||
<p>A simple mapping to convert a 0-1 range to a 0-100 range would be:</p>
|
||
<pre><code class="hljs css javascript">value.interpolate({
|
||
<span class="hljs-attr">inputRange</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>],
|
||
<span class="hljs-attr">outputRange</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">100</span>],
|
||
});
|
||
</code></pre>
|
||
<p>For example, you may want to think about your <code>Animated.Value</code> as going from 0 to 1,
|
||
but animate the position from 150px to 0px and the opacity from 0 to 1.
|
||
This can easily be done by modifying <code>style</code> from the example above like so:</p>
|
||
<pre><code class="hljs css javascript"> style={{
|
||
<span class="hljs-attr">opacity</span>: <span class="hljs-keyword">this</span>.state.fadeAnim, <span class="hljs-comment">// Binds directly</span>
|
||
transform: [{
|
||
<span class="hljs-attr">translateY</span>: <span class="hljs-keyword">this</span>.state.fadeAnim.interpolate({
|
||
<span class="hljs-attr">inputRange</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>],
|
||
<span class="hljs-attr">outputRange</span>: [<span class="hljs-number">150</span>, <span class="hljs-number">0</span>] <span class="hljs-comment">// 0 : 150, 0.5 : 75, 1 : 0</span>
|
||
}),
|
||
}],
|
||
}}
|
||
</code></pre>
|
||
<p><a href="/react-native/docs/animated.html#interpolate"><code>interpolate()</code></a> supports multiple range segments as well, which is handy for defining dead zones and other handy tricks.
|
||
For example, to get an negation relationship at -300 that goes to 0 at -100, then back up to 1 at 0, and then back down to zero at 100 followed by a dead-zone that remains at 0 for everything beyond that, you could do:</p>
|
||
<pre><code class="hljs css javascript">value.interpolate({
|
||
<span class="hljs-attr">inputRange</span>: [<span class="hljs-number">-300</span>, <span class="hljs-number">-100</span>, <span class="hljs-number">0</span>, <span class="hljs-number">100</span>, <span class="hljs-number">101</span>],
|
||
<span class="hljs-attr">outputRange</span>: [<span class="hljs-number">300</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>],
|
||
});
|
||
</code></pre>
|
||
<p>Which would map like so:</p>
|
||
<pre><code class="hljs">Input | Output
|
||
------|-------
|
||
<span class="hljs-number">-400</span>| <span class="hljs-number">450</span>
|
||
<span class="hljs-number">-300</span>| <span class="hljs-number">300</span>
|
||
<span class="hljs-number">-200</span>| <span class="hljs-number">150</span>
|
||
<span class="hljs-number">-100</span>| <span class="hljs-number">0</span>
|
||
<span class="hljs-number">-50</span>| <span class="hljs-number">0.5</span>
|
||
<span class="hljs-number">0</span>| <span class="hljs-number">1</span>
|
||
<span class="hljs-number">50</span>| <span class="hljs-number">0.5</span>
|
||
<span class="hljs-number">100</span>| <span class="hljs-number">0</span>
|
||
<span class="hljs-number">101</span>| <span class="hljs-number">0</span>
|
||
<span class="hljs-number">200</span>| <span class="hljs-number">0</span>
|
||
</code></pre>
|
||
<p><code>interpolate()</code> also supports mapping to strings, allowing you to animate colors as well as values with units. For example, if you wanted to animate a rotation you could do:</p>
|
||
<pre><code class="hljs css javascript">value.interpolate({
|
||
<span class="hljs-attr">inputRange</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">360</span>],
|
||
<span class="hljs-attr">outputRange</span>: [<span class="hljs-string">'0deg'</span>, <span class="hljs-string">'360deg'</span>]
|
||
})
|
||
</code></pre>
|
||
<p><code>interpolate()</code> also supports arbitrary easing functions, many of which are already implemented in the
|
||
<a href="/react-native/docs/easing.html"><code>Easing</code></a> module.
|
||
<code>interpolate()</code> also has configurable behavior for extrapolating the <code>outputRange</code>.
|
||
You can set the extrapolation by setting the <code>extrapolate</code>, <code>extrapolateLeft</code>, or <code>extrapolateRight</code> options.
|
||
The default value is <code>extend</code> but you can use <code>clamp</code> to prevent the output value from exceeding <code>outputRange</code>.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="tracking-dynamic-values"></a><a href="#tracking-dynamic-values" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tracking dynamic values</h3>
|
||
<p>Animated values can also track other values.
|
||
Just set the <code>toValue</code> of an animation to another animated value instead of a plain number.
|
||
For example, a "Chat Heads" animation like the one used by Messenger on Android could be implemented with a <code>spring()</code> pinned on another animated value, or with <code>timing()</code> and a <code>duration</code> of 0 for rigid tracking.
|
||
They can also be composed with interpolations:</p>
|
||
<pre><code class="hljs css javascript">Animated.spring(follower, {<span class="hljs-attr">toValue</span>: leader}).start();
|
||
Animated.timing(opacity, {
|
||
<span class="hljs-attr">toValue</span>: pan.x.interpolate({
|
||
<span class="hljs-attr">inputRange</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">300</span>],
|
||
<span class="hljs-attr">outputRange</span>: [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>],
|
||
}),
|
||
}).start();
|
||
</code></pre>
|
||
<p>The <code>leader</code> and <code>follower</code> animated values would be implemented using <code>Animated.ValueXY()</code>.
|
||
<code>ValueXY</code> is a handy way to deal with 2D interactions, such as panning or dragging.
|
||
It is a simple wrapper that basically contains two <code>Animated.Value</code> instances and some helper functions that call through to them,
|
||
making <code>ValueXY</code> a drop-in replacement for <code>Value</code> in many cases.
|
||
It allows us to track both x and y values in the example above.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="tracking-gestures"></a><a href="#tracking-gestures" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tracking gestures</h3>
|
||
<p>Gestures, like panning or scrolling, and other events can map directly to animated values using <a href="/react-native/docs/animated.html#event"><code>Animated.event</code></a>.
|
||
This is done with a structured map syntax so that values can be extracted from complex event objects.
|
||
The first level is an array to allow mapping across multiple args, and that array contains nested objects.</p>
|
||
<p>For example, when working with horizontal scrolling gestures,
|
||
you would do the following in order to map <code>event.nativeEvent.contentOffset.x</code> to <code>scrollX</code> (an <code>Animated.Value</code>):</p>
|
||
<pre><code class="hljs css javascript"> onScroll={Animated.event(
|
||
<span class="hljs-comment">// scrollX = e.nativeEvent.contentOffset.x</span>
|
||
[{ <span class="hljs-attr">nativeEvent</span>: {
|
||
<span class="hljs-attr">contentOffset</span>: {
|
||
<span class="hljs-attr">x</span>: scrollX
|
||
}
|
||
}
|
||
}]
|
||
)}
|
||
</code></pre>
|
||
<p>When using <code>PanResponder</code>, you could use the following code to extract the x and y positions from <code>gestureState.dx</code> and <code>gestureState.dy</code>.
|
||
We use a <code>null</code> in the first position of the array, as we are only interested in the second argument passed to the <code>PanResponder</code> handler,
|
||
which is the <code>gestureState</code>.</p>
|
||
<pre><code class="hljs css javascript">onPanResponderMove={Animated.event(
|
||
[<span class="hljs-literal">null</span>, <span class="hljs-comment">// ignore the native event</span>
|
||
<span class="hljs-comment">// extract dx and dy from gestureState</span>
|
||
<span class="hljs-comment">// like 'pan.x = gestureState.dx, pan.y = gestureState.dy'</span>
|
||
{<span class="hljs-attr">dx</span>: pan.x, <span class="hljs-attr">dy</span>: pan.y}
|
||
])}
|
||
</code></pre>
|
||
<h3><a class="anchor" aria-hidden="true" name="responding-to-the-current-animation-value"></a><a href="#responding-to-the-current-animation-value" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Responding to the current animation value</h3>
|
||
<p>You may notice that there is no obvious way to read the current value while animating.
|
||
This is because the value may only be known in the native runtime due to optimizations.
|
||
If you need to run JavaScript in response to the current value, there are two approaches:</p>
|
||
<ul>
|
||
<li><code>spring.stopAnimation(callback)</code> will stop the animation and invoke <code>callback</code> with the final value. This is useful when making gesture transitions.</li>
|
||
<li><code>spring.addListener(callback)</code> will invoke <code>callback</code> asynchronously while the animation is running, providing a recent value.
|
||
This is useful for triggering state changes,
|
||
for example snapping a bobble to a new option as the user drags it closer,
|
||
because these larger state changes are less sensitive to a few frames of lag compared to continuous gestures like panning which need to run at 60 fps.</li>
|
||
</ul>
|
||
<p><code>Animated</code> is designed to be fully serializable so that animations can be run in a high performance way, independent of the normal JavaScript event loop.
|
||
This does influence the API, so keep that in mind when it seems a little trickier to do something compared to a fully synchronous system.
|
||
Check out <code>Animated.Value.addListener</code> as a way to work around some of these limitations,
|
||
but use it sparingly since it might have performance implications in the future.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="using-the-native-driver"></a><a href="#using-the-native-driver" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using the native driver</h3>
|
||
<p>The <code>Animated</code> API is designed to be serializable.
|
||
By using the <a href="http://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html">native driver</a>,
|
||
we send everything about the animation to native before starting the animation,
|
||
allowing native code to perform the animation on the UI thread without having to go through the bridge on every frame.
|
||
Once the animation has started, the JS thread can be blocked without affecting the animation.</p>
|
||
<p>Using the native driver for normal animations is quite simple.
|
||
Just add <code>useNativeDriver: true</code> to the animation config when starting it.</p>
|
||
<pre><code class="hljs css javascript">Animated.timing(<span class="hljs-keyword">this</span>.state.animatedValue, {
|
||
<span class="hljs-attr">toValue</span>: <span class="hljs-number">1</span>,
|
||
<span class="hljs-attr">duration</span>: <span class="hljs-number">500</span>,
|
||
<span class="hljs-attr">useNativeDriver</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// <-- Add this</span>
|
||
}).start();
|
||
</code></pre>
|
||
<p>Animated values are only compatible with one driver so if you use native driver when starting an animation on a value,
|
||
make sure every animation on that value also uses the native driver.</p>
|
||
<p>The native driver also works with <code>Animated.event</code>.
|
||
This is specially useful for animations that follow the scroll position as without the native driver,
|
||
the animation will always run a frame behind the gesture due to the async nature of React Native.</p>
|
||
<pre><code class="hljs css javascript"><Animated.ScrollView // <-- Use the Animated ScrollView wrapper
|
||
scrollEventThrottle={1} // <-- Use 1 here to make sure no events are ever missed
|
||
onScroll={Animated.event(
|
||
[{ nativeEvent: { contentOffset: { y: this.state.animatedValue } } }],
|
||
{ useNativeDriver: true } // <-- Add this
|
||
)}
|
||
>
|
||
{content}
|
||
</Animated.ScrollView>
|
||
</code></pre>
|
||
<p>You can see the native driver in action by running the <a href="https://github.com/facebook/react-native/blob/master/RNTester/">RNTester app</a>,
|
||
then loading the Native Animated Example.
|
||
You can also take a look at the <a href="https://github.com/facebook/react-native/blob/master/RNTester/js/NativeAnimationsExample.js">source code</a> to learn how these examples were produced.</p>
|
||
<h4><a class="anchor" aria-hidden="true" name="caveats"></a><a href="#caveats" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Caveats</h4>
|
||
<p>Not everything you can do with <code>Animated</code> is currently supported by the native driver.
|
||
The main limitation is that you can only animate non-layout properties:
|
||
things like <code>transform</code> and <code>opacity</code> will work, but flexbox and position properties will not.
|
||
When using <code>Animated.event</code>, it will only work with direct events and not bubbling events.
|
||
This means it does not work with <code>PanResponder</code> but does work with things like <code>ScrollView#onScroll</code>.</p>
|
||
<p>When an animation is running, it can prevent <code>VirtualizedList</code> components from rendering more rows. If you need to run a long or looping animation while the user is scrolling through a list, you can use <code>isInteraction: false</code> in your animation's config to prevent this issue.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="bear-in-mind"></a><a href="#bear-in-mind" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bear in mind</h3>
|
||
<p>While using transform styles such as <code>rotateY</code>, <code>rotateX</code>, and others ensure the transform style <code>perspective</code> is in place.
|
||
At this time some animations may not render on Android without it. Example below.</p>
|
||
<pre><code class="hljs css javascript"><Animated.View
|
||
style={{
|
||
<span class="hljs-attr">transform</span>: [
|
||
{ <span class="hljs-attr">scale</span>: <span class="hljs-keyword">this</span>.state.scale },
|
||
{ <span class="hljs-attr">rotateY</span>: <span class="hljs-keyword">this</span>.state.rotateY },
|
||
{ <span class="hljs-attr">perspective</span>: <span class="hljs-number">1000</span> } <span class="hljs-comment">// without this line this Animation will not render on Android while working fine on iOS</span>
|
||
]
|
||
}}
|
||
/>
|
||
</code></pre>
|
||
<h3><a class="anchor" aria-hidden="true" name="additional-examples"></a><a href="#additional-examples" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Additional examples</h3>
|
||
<p>The RNTester app has various examples of <code>Animated</code> in use:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/facebook/react-native/tree/master/RNTester/js/AnimatedGratuitousApp">AnimatedGratuitousApp</a></li>
|
||
<li><a href="https://github.com/facebook/react-native/blob/master/RNTester/js/NativeAnimationsExample.js">NativeAnimationsExample</a></li>
|
||
</ul>
|
||
<h2><a class="anchor" aria-hidden="true" name="layoutanimation-api"></a><a href="#layoutanimation-api" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>LayoutAnimation</code> API</h2>
|
||
<p><code>LayoutAnimation</code> allows you to globally configure <code>create</code> and <code>update</code>
|
||
animations that will be used for all views in the next render/layout cycle.
|
||
This is useful for doing flexbox layout updates without bothering to measure or
|
||
calculate specific properties in order to animate them directly, and is
|
||
especially useful when layout changes may affect ancestors, for example a "see
|
||
more" expansion that also increases the size of the parent and pushes down the
|
||
row below which would otherwise require explicit coordination between the
|
||
components in order to animate them all in sync.</p>
|
||
<p>Note that although <code>LayoutAnimation</code> is very powerful and can be quite useful,
|
||
it provides much less control than <code>Animated</code> and other animation libraries, so
|
||
you may need to use another approach if you can't get <code>LayoutAnimation</code> to do
|
||
what you want.</p>
|
||
<p>Note that in order to get this to work on <strong>Android</strong> you need to set the following flags via <code>UIManager</code>:</p>
|
||
<pre><code class="hljs css javascript">UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(<span class="hljs-literal">true</span>);
|
||
</code></pre>
|
||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||
<span class="hljs-keyword">import</span> {
|
||
NativeModules,
|
||
LayoutAnimation,
|
||
Text,
|
||
TouchableOpacity,
|
||
StyleSheet,
|
||
View,
|
||
} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||
|
||
<span class="hljs-keyword">const</span> { UIManager } = NativeModules;
|
||
|
||
UIManager.setLayoutAnimationEnabledExperimental &&
|
||
UIManager.setLayoutAnimationEnabledExperimental(<span class="hljs-literal">true</span>);
|
||
|
||
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
|
||
state = {
|
||
<span class="hljs-attr">w</span>: <span class="hljs-number">100</span>,
|
||
<span class="hljs-attr">h</span>: <span class="hljs-number">100</span>,
|
||
};
|
||
|
||
_onPress = <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||
<span class="hljs-comment">// Animate the update</span>
|
||
LayoutAnimation.spring();
|
||
<span class="hljs-keyword">this</span>.setState({<span class="hljs-attr">w</span>: <span class="hljs-keyword">this</span>.state.w + <span class="hljs-number">15</span>, <span class="hljs-attr">h</span>: <span class="hljs-keyword">this</span>.state.h + <span class="hljs-number">15</span>})
|
||
}
|
||
|
||
render() {
|
||
<span class="hljs-keyword">return</span> (
|
||
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>></span>
|
||
<span class="hljs-tag"><<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{[styles.box,</span> {<span class="hljs-attr">width:</span> <span class="hljs-attr">this.state.w</span>, <span class="hljs-attr">height:</span> <span class="hljs-attr">this.state.h</span>}]} /></span>
|
||
<span class="hljs-tag"><<span class="hljs-name">TouchableOpacity</span> <span class="hljs-attr">onPress</span>=<span class="hljs-string">{this._onPress}</span>></span>
|
||
<span class="hljs-tag"><<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.button}</span>></span>
|
||
<span class="hljs-tag"><<span class="hljs-name">Text</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.buttonText}</span>></span>Press me!<span class="hljs-tag"></<span class="hljs-name">Text</span>></span>
|
||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||
<span class="hljs-tag"></<span class="hljs-name">TouchableOpacity</span>></span>
|
||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||
);
|
||
}
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
},
|
||
box: {
|
||
width: 200,
|
||
height: 200,
|
||
backgroundColor: 'red',
|
||
},
|
||
button: {
|
||
backgroundColor: 'black',
|
||
paddingHorizontal: 20,
|
||
paddingVertical: 15,
|
||
marginTop: 15,
|
||
},
|
||
buttonText: {
|
||
color: '#fff',
|
||
fontWeight: 'bold',
|
||
},
|
||
});
|
||
</span></code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||
data-snack-name="Example"
|
||
data-snack-description="Example usage"
|
||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%0A%20%20NativeModules%2C%0A%20%20LayoutAnimation%2C%0A%20%20Text%2C%0A%20%20TouchableOpacity%2C%0A%20%20StyleSheet%2C%0A%20%20View%2C%0A%7D%20from%20'react-native'%3B%0A%0Aconst%20%7B%20UIManager%20%7D%20%3D%20NativeModules%3B%0A%0AUIManager.setLayoutAnimationEnabledExperimental%20%26%26%0A%20%20UIManager.setLayoutAnimationEnabledExperimental(true)%3B%0A%0Aexport%20default%20class%20App%20extends%20React.Component%20%7B%0A%20%20state%20%3D%20%7B%0A%20%20%20%20w%3A%20100%2C%0A%20%20%20%20h%3A%20100%2C%0A%20%20%7D%3B%0A%0A%20%20_onPress%20%3D%20()%20%3D%3E%20%7B%0A%20%20%20%20%2F%2F%20Animate%20the%20update%0A%20%20%20%20LayoutAnimation.spring()%3B%0A%20%20%20%20this.setState(%7Bw%3A%20this.state.w%20%2B%2015%2C%20h%3A%20this.state.h%20%2B%2015%7D)%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%5Bstyles.box%2C%20%7Bwidth%3A%20this.state.w%2C%20height%3A%20this.state.h%7D%5D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPress%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3EPress%20me!%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20flex%3A%201%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20box%3A%20%7B%0A%20%20%20%20width%3A%20200%2C%0A%20%20%20%20height%3A%20200%2C%0A%20%20%20%20backgroundColor%3A%20'red'%2C%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20backgroundColor%3A%20'black'%2C%0A%20%20%20%20paddingHorizontal%3A%2020%2C%0A%20%20%20%20paddingVertical%3A%2015%2C%0A%20%20%20%20marginTop%3A%2015%2C%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20color%3A%20'%23fff'%2C%0A%20%20%20%20fontWeight%3A%20'bold'%2C%0A%20%20%7D%2C%0A%7D)%3B%0A"
|
||
data-snack-platform="ios"
|
||
data-snack-preview="true"
|
||
data-snack-sdk-version="23.0.0"
|
||
style="
|
||
overflow: hidden;
|
||
background: #fafafa;
|
||
border: 1px solid rgba(0,0,0,.16);
|
||
border-radius: 4px;
|
||
height: 514px;
|
||
width: 880px;
|
||
"
|
||
></div></div></div><p>This example uses a preset value, you can customize the animations as
|
||
you need, see <a href="https://github.com/facebook/react-native/blob/master/Libraries/LayoutAnimation/LayoutAnimation.js">LayoutAnimation.js</a>
|
||
for more information.</p>
|
||
<h2><a class="anchor" aria-hidden="true" name="additional-notes"></a><a href="#additional-notes" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Additional notes</h2>
|
||
<h3><a class="anchor" aria-hidden="true" name="requestanimationframe"></a><a href="#requestanimationframe" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>requestAnimationFrame</code></h3>
|
||
<p><code>requestAnimationFrame</code> is a polyfill from the browser that you might be
|
||
familiar with. It accepts a function as its only argument and calls that
|
||
function before the next repaint. It is an essential building block for
|
||
animations that underlies all of the JavaScript-based animation APIs. In
|
||
general, you shouldn't need to call this yourself - the animation APIs will
|
||
manage frame updates for you.</p>
|
||
<h3><a class="anchor" aria-hidden="true" name="setnativeprops"></a><a href="#setnativeprops" aria-hidden="true" class="hash-link" ><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>setNativeProps</code></h3>
|
||
<p>As mentioned <a href="/react-native/docs/direct-manipulation.html">in the Direct Manipulation section</a>,
|
||
<code>setNativeProps</code> allows us to modify properties of native-backed
|
||
components (components that are actually backed by native views, unlike
|
||
composite components) directly, without having to <code>setState</code> and
|
||
re-render the component hierarchy.</p>
|
||
<p>We could use this in the Rebound example to update the scale - this
|
||
might be helpful if the component that we are updating is deeply nested
|
||
and hasn't been optimized with <code>shouldComponentUpdate</code>.</p>
|
||
<p>If you find your animations with dropping frames (performing below 60 frames
|
||
per second), look into using <code>setNativeProps</code> or <code>shouldComponentUpdate</code> to
|
||
optimize them. Or you could run the animations on the UI thread rather than
|
||
the JavaScript thread <a href="http://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html">with the useNativeDriver
|
||
option</a>.
|
||
You may also want to defer any computationally intensive work until after
|
||
animations are complete, using the
|
||
<a href="/react-native/docs/interactionmanager.html">InteractionManager</a>. You can monitor the
|
||
frame rate by using the In-App Developer Menu "FPS Monitor" tool.</p>
|
||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="images.html">← Images</a><a class="docs-next button" href="accessibility.html">Accessibility →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Learn the Basics</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://www.meetup.com/topics/react-native/" target="_blank">Meetups</a><a href="https://www.facebook.com/groups/react.native.community" target="_blank">Facebook Group</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a></div><div><h5><a href="/react-native/help.html">Help</a></h5><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a><a href="/react-native/versions.html" target="_blank">Latest Releases</a><a href="https://react-native.canny.io/feature-requests" target="_blank">Feature Requests</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="http://reactjs.org" target="_blank">React</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><div class="githubButton"><a class="github-button" href="https://github.com/facebook/react-native" data-icon="octicon-star" data-show-count="true" data-count-href="/facebook/react-native/stargazers" data-count-api="/repos/facebook/react-native#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star facebook/react-native on GitHub">Star</a></div></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2017 Facebook Inc.</section></footer></div><script type="text/javascript" src="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>
|
||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||
|
||
ga('create', 'UA-41298772-2', 'auto');
|
||
ga('send', 'pageview');
|
||
</script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||
var search = docsearch({
|
||
apiKey: '2c98749b4a1e588efec53b2acec13025',
|
||
indexName: 'react-native-versions',
|
||
inputSelector: '#search_input_react',
|
||
algoliaOptions: {"facetFilters":["tags:0.51"],"hitsPerPage":5}
|
||
});
|
||
</script></body></html> |