react-native/Libraries
Adam Miskiewicz 26133beda9 Add closed-form damped harmonic oscillator algorithm to Animated.spring
Summary:
As I was working on mimicking iOS animations for my ongoing work with `react-navigation`, one task I had was to match the "push from right" animation that is common in UINavigationController.

I was able to grab the exact animation values for this animation with some LLDB magic, and found that the screen is animated using a `CASpringAnimation` with the parameters:

- stiffness: 1000
- damping: 500
- mass: 3

After spending a considerable amount of time attempting to replicate the spring created with these values by CASpringAnimation by specifying values for tension and friction in the current `Animated.spring` implementation, I was unable to come up with mathematically equivalent values that could replicate the spring _exactly_.

After doing some research, I ended up disassembling the QuartzCore framework, reading the assembly, and determined that Apple's implementation of `CASpringAnimation` does not use an integrated, numerical animation model as we do in Animated.spring, but instead solved for the closed form of the equations that govern damped harmonic oscillation (the differential equations themselves are [here](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator), and a paper describing the math to arrive at the closed-form solution to the second-order ODE that describes the DHO is [here](http://planetmath.org/sites/default/files/texpdf/39745.pdf)).

Though we can get the currently implemented RK4 integration close by tweaking some values, it is, the current model is at it's core, an approximation. It seemed that if I wanted to implement the `CASpringAnimation` behavior _exactly_, I needed to implement the analytical model (as is implemented in `CASpringAnimation`) in `Animated`.

We add three new optional parameters to `Animated.spring` (to both the JS and native implementations):

- `stiffness`, a value describing the spring's stiffness coefficient
- `damping`, a value defining how the spring's motion should be damped due to the forces of friction (technically called the _viscous damping coefficient_).
- `mass`, a value describing the mass of the object attached to the end of the simulated spring

Just like if a developer were to specify `bounciness`/`speed` and `tension`/`friction` in the same config, specifying any of these new parameters while also specifying the aforementioned config values will cause an error to be thrown.

~Defaults for `Animated.spring` across all three implementations (JS/iOS/Android) stay the same, so this is intended to be *a non-breaking change*.~

~If `stiffness`, `damping`, or `mass` are provided in the config, we switch to animating the spring with the new damped harmonic oscillator model (`DHO` as described in the code).~

We replace the old RK4 integration implementation with our new analytic implementation. Tension/friction nicely correspond directly to stiffness/damping with the mass of the spring locked at 1. This is intended to be *a non-breaking change*, but there may be very slight differences in people's springs (maybe not even noticeable to the naked eye), given the fact that this implementation is more accurate.

The DHO animation algorithm will calculate the _position_ of the spring at time _t_ explicitly and in an analytical fashion, and use this calculation to update the animation's value. It will also analytically calculate the velocity at time _t_, so as to allow animated value tracking to continue to work as expected.

Also, docs have been updated to cover the new configuration options (and also I added docs for Animated configuration options that were missing, such as `restDisplacementThreshold`, etc).

Run tests. Run "Animated Gratuitous App" and "NativeAnimation" example in RNTester.
Closes https://github.com/facebook/react-native/pull/15322

Differential Revision: D5794791

Pulled By: hramos

fbshipit-source-id: 58ed9e134a097e321c85c417a142576f6a8952f8
2017-09-20 23:38:16 -07:00
..
ART ReactNative sync (c3718c4...abce30f): the one about the Prepack optimizations 2017-09-14 18:17:17 -07:00
ActionSheetIOS Standardize project indentation settings on 2 spaces 2017-07-31 05:20:03 -07:00
Alert support null titles in AlertIOS 2017-09-11 16:08:03 -07:00
Animated Add closed-form damped harmonic oscillator algorithm to Animated.spring 2017-09-20 23:38:16 -07:00
AppState Avoid race condition for AppState.currentState 2017-08-18 13:14:59 -07:00
BatchedBridge Reverting changes to MessageQueue 2017-09-07 14:30:59 -07:00
Blob @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
BugReporting Patch up for future React Sync 2017-02-08 14:50:43 -08:00
CameraRoll Fix crash when trying to load photo library assets with nil image url 2017-09-14 12:02:27 -07:00
Components Add props for overriding native component 2017-09-19 16:01:02 -07:00
Core Add missing delete to requestIdleCallback 2017-09-11 18:15:49 -07:00
EventEmitter Turn on Flow for EventEmitter 2017-08-30 11:52:28 -07:00
Experimental @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
Geolocation @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
Image BREAKING: Removed support of nested content inside <Image> on Android 2017-09-17 21:34:28 -07:00
Inspector @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
Interaction Reverting changes to MessageQueue 2017-09-07 14:30:59 -07:00
JSInspector Add Network agent 2016-11-02 12:29:15 -07:00
LayoutAnimation @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
Linking fix flow warning and typo 2017-09-08 14:46:14 -07:00
LinkingIOS Standardize project indentation settings on 2 spaces 2017-07-31 05:20:03 -07:00
Lists Fix Flow errors in ListViewData source. 2017-09-19 16:57:41 -07:00
Modal Upgrade fbsource/xplat/js to Flow v0.53.0 2017-08-17 18:45:01 -07:00
NativeAnimation Add closed-form damped harmonic oscillator algorithm to Animated.spring 2017-09-20 23:38:16 -07:00
Network Migrate tests away from "jsdom" environment 2017-09-11 09:49:11 -07:00
Performance Gate more code with if (__DEV__) { } 2017-08-14 07:19:00 -07:00
PermissionsAndroid Update documentation for PermissionsAndroid 2017-08-16 15:01:51 -07:00
PushNotificationIOS Fix flowtype errors for PushNotificationIOS 2017-08-14 12:03:18 -07:00
RCTTest Increase RCTTestRunner timeouts 2017-08-25 10:00:39 -07:00
ReactNative Native view manager event types exposed to JS via view config 2017-09-14 18:17:17 -07:00
Renderer React sync for revisions abce30f...b5ac963 2017-09-18 16:45:26 -07:00
Sample Standardize project indentation settings on 2 spaces 2017-07-31 05:20:03 -07:00
Settings Fix infinite recursion in RCTSettingsManager init 2017-08-09 09:39:40 -07:00
Share Fix error in flow types 2017-09-12 05:50:26 -07:00
Storage correctly order ASyncStorage 2017-02-21 15:18:40 -08:00
StyleSheet Fix stylesheet registery 2017-08-23 08:54:39 -07:00
Text Fixed issue with measuring text with NaN width 2017-09-19 14:16:41 -07:00
Utilities @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
Vibration fix and enrich Vibration docs 2017-08-23 20:45:45 -07:00
WebSocket @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
fishhook Merge fishhook.xcodeproj in RCTWebSocket 2017-08-09 07:48:09 -07:00
polyfills Use proper script way to clone Emoji files from www 2017-08-21 16:29:39 -07:00
react-native Add Android React Native Checkbox 2017-08-25 10:30:54 -07:00
vendor @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
.eslintrc Disallow trailing commas in react-native-github 2017-08-17 16:20:04 -07:00
Promise.js @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00
promiseRejectionIsError.js @allow-large-files Flow v0.54.0 2017-09-06 03:33:43 -07:00