From afdeefc864cce238c41656855240520fb2f4fc12 Mon Sep 17 00:00:00 2001 From: Christopher Chedeau Date: Mon, 3 Aug 2015 15:15:07 -0700 Subject: [PATCH] [Animated] Remove rebound dependency Summary: We already reimplement the spring computation, we were only using rebound for the tension/friction conversion. Turns out that it is quite small so we can just embed it. I'm doing this as I'm preparing for doing a web version of the feature and I'm trying to minimize the number of dependencies. https://github.com/facebook/rebound-js/blob/master/rebound.js#L932 --- Libraries/Animation/Animated/Animated.js | 6 +- Libraries/Animation/Animated/SpringConfig.js | 102 +++++++++++++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 Libraries/Animation/Animated/SpringConfig.js diff --git a/Libraries/Animation/Animated/Animated.js b/Libraries/Animation/Animated/Animated.js index 8f3f38398..221c153f9 100644 --- a/Libraries/Animation/Animated/Animated.js +++ b/Libraries/Animation/Animated/Animated.js @@ -17,12 +17,12 @@ var InteractionManager = require('InteractionManager'); var Interpolation = require('Interpolation'); var React = require('React'); var Set = require('Set'); +var SpringConfig = require('SpringConfig'); var Text = require('Text'); var View = require('View'); var invariant = require('invariant'); var flattenStyle = require('flattenStyle'); -var rebound = require('rebound'); var requestAnimationFrame = require('requestAnimationFrame'); import type InterpolationConfigType from 'Interpolation'; @@ -351,12 +351,12 @@ class SpringAnimation extends Animation { config.tension === undefined && config.friction === undefined, 'You can only define bounciness/speed or tension/friction but not both', ); - springConfig = rebound.SpringConfig.fromBouncinessAndSpeed( + springConfig = SpringConfig.fromBouncinessAndSpeed( withDefault(config.bounciness, 8), withDefault(config.speed, 12), ); } else { - springConfig = rebound.SpringConfig.fromOrigamiTensionAndFriction( + springConfig = SpringConfig.fromOrigamiTensionAndFriction( withDefault(config.tension, 40), withDefault(config.friction, 7), ); diff --git a/Libraries/Animation/Animated/SpringConfig.js b/Libraries/Animation/Animated/SpringConfig.js new file mode 100644 index 000000000..d10abced2 --- /dev/null +++ b/Libraries/Animation/Animated/SpringConfig.js @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * 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. + * + * @providesModule SpringConfig + * @flow + */ + +'use strict'; + +type SpringConfigType = { + tension: number, + friction: number, +}; + +function tensionFromOrigamiValue(oValue) { + return (oValue - 30) * 3.62 + 194; +} + +function frictionFromOrigamiValue(oValue) { + return (oValue - 8) * 3 + 25; +} + +function fromOrigamiTensionAndFriction( + tension: number, + friction: number, +): SpringConfigType { + return { + tension: tensionFromOrigamiValue(tension), + friction: frictionFromOrigamiValue(friction) + }; +} + +function fromBouncinessAndSpeed( + bounciness: number, + speed: number, +): SpringConfigType { + function normalize(value, startValue, endValue) { + return (value - startValue) / (endValue - startValue); + } + + function projectNormal(n, start, end) { + return start + (n * (end - start)); + } + + function linearInterpolation(t, start, end) { + return t * end + (1 - t) * start; + } + + function quadraticOutInterpolation(t, start, end) { + return linearInterpolation(2 * t - t * t, start, end); + } + + function b3Friction1(x) { + return (0.0007 * Math.pow(x, 3)) - + (0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28; + } + + function b3Friction2(x) { + return (0.000044 * Math.pow(x, 3)) - + (0.006 * Math.pow(x, 2)) + 0.36 * x + 2; + } + + function b3Friction3(x) { + return (0.00000045 * Math.pow(x, 3)) - + (0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84; + } + + function b3Nobounce(tension) { + if (tension <= 18) { + return b3Friction1(tension); + } else if (tension > 18 && tension <= 44) { + return b3Friction2(tension); + } else { + return b3Friction3(tension); + } + } + + var b = normalize(bounciness / 1.7, 0, 20); + b = projectNormal(b, 0, 0.8); + var s = normalize(speed / 1.7, 0, 20); + var bouncyTension = projectNormal(s, 0.5, 200); + var bouncyFriction = quadraticOutInterpolation( + b, + b3Nobounce(bouncyTension), + 0.01 + ); + + return { + tension: tensionFromOrigamiValue(bouncyTension), + friction: frictionFromOrigamiValue(bouncyFriction) + }; +} + +module.exports = { + fromOrigamiTensionAndFriction, + fromBouncinessAndSpeed, +};