From b9a31eb547c83c1315e7d7a46735b632bde70eee Mon Sep 17 00:00:00 2001 From: Jake Schafer Date: Mon, 9 Jan 2023 21:15:46 -0600 Subject: [PATCH 1/2] added react native lib --- third_party/react-native/LICENSE.txt | 21 + .../Animated/animations/SpringAnimation.js | 370 ++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 third_party/react-native/LICENSE.txt create mode 100644 third_party/react-native/Libraries/Animated/animations/SpringAnimation.js diff --git a/third_party/react-native/LICENSE.txt b/third_party/react-native/LICENSE.txt new file mode 100644 index 0000000000000..b93be90515ccd --- /dev/null +++ b/third_party/react-native/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third_party/react-native/Libraries/Animated/animations/SpringAnimation.js b/third_party/react-native/Libraries/Animated/animations/SpringAnimation.js new file mode 100644 index 0000000000000..69101dab030e8 --- /dev/null +++ b/third_party/react-native/Libraries/Animated/animations/SpringAnimation.js @@ -0,0 +1,370 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type {PlatformConfig} from '../AnimatedPlatformConfig'; +import type AnimatedInterpolation from '../nodes/AnimatedInterpolation'; +import type AnimatedValue from '../nodes/AnimatedValue'; +import type AnimatedValueXY from '../nodes/AnimatedValueXY'; +import type {AnimationConfig, EndCallback} from './Animation'; + +import NativeAnimatedHelper from '../NativeAnimatedHelper'; +import AnimatedColor from '../nodes/AnimatedColor'; +import * as SpringConfig from '../SpringConfig'; +import Animation from './Animation'; +import invariant from 'invariant'; + +export type SpringAnimationConfig = { + ...AnimationConfig, + toValue: + | number + | AnimatedValue + | { + x: number, + y: number, + ... + } + | AnimatedValueXY + | { + r: number, + g: number, + b: number, + a: number, + ... + } + | AnimatedColor + | AnimatedInterpolation, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: + | number + | { + x: number, + y: number, + ... + }, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, +}; + +export type SpringAnimationConfigSingle = { + ...AnimationConfig, + toValue: number, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: number, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, +}; + +export default class SpringAnimation extends Animation { + _overshootClamping: boolean; + _restDisplacementThreshold: number; + _restSpeedThreshold: number; + _lastVelocity: number; + _startPosition: number; + _lastPosition: number; + _fromValue: number; + _toValue: number; + _stiffness: number; + _damping: number; + _mass: number; + _initialVelocity: number; + _delay: number; + _timeout: any; + _startTime: number; + _lastTime: number; + _frameTime: number; + _onUpdate: (value: number) => void; + _animationFrame: any; + _useNativeDriver: boolean; + _platformConfig: ?PlatformConfig; + + constructor(config: SpringAnimationConfigSingle) { + super(); + + this._overshootClamping = config.overshootClamping ?? false; + this._restDisplacementThreshold = config.restDisplacementThreshold ?? 0.001; + this._restSpeedThreshold = config.restSpeedThreshold ?? 0.001; + this._initialVelocity = config.velocity ?? 0; + this._lastVelocity = config.velocity ?? 0; + this._toValue = config.toValue; + this._delay = config.delay ?? 0; + this._useNativeDriver = NativeAnimatedHelper.shouldUseNativeDriver(config); + this._platformConfig = config.platformConfig; + this.__isInteraction = config.isInteraction ?? !this._useNativeDriver; + this.__iterations = config.iterations ?? 1; + + if ( + config.stiffness !== undefined || + config.damping !== undefined || + config.mass !== undefined + ) { + invariant( + config.bounciness === undefined && + config.speed === undefined && + config.tension === undefined && + config.friction === undefined, + 'You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one', + ); + this._stiffness = config.stiffness ?? 100; + this._damping = config.damping ?? 10; + this._mass = config.mass ?? 1; + } else if (config.bounciness !== undefined || config.speed !== undefined) { + // Convert the origami bounciness/speed values to stiffness/damping + // We assume mass is 1. + invariant( + config.tension === undefined && + config.friction === undefined && + config.stiffness === undefined && + config.damping === undefined && + config.mass === undefined, + 'You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one', + ); + const springConfig = SpringConfig.fromBouncinessAndSpeed( + config.bounciness ?? 8, + config.speed ?? 12, + ); + this._stiffness = springConfig.stiffness; + this._damping = springConfig.damping; + this._mass = 1; + } else { + // Convert the origami tension/friction values to stiffness/damping + // We assume mass is 1. + const springConfig = SpringConfig.fromOrigamiTensionAndFriction( + config.tension ?? 40, + config.friction ?? 7, + ); + this._stiffness = springConfig.stiffness; + this._damping = springConfig.damping; + this._mass = 1; + } + + invariant(this._stiffness > 0, 'Stiffness value must be greater than 0'); + invariant(this._damping > 0, 'Damping value must be greater than 0'); + invariant(this._mass > 0, 'Mass value must be greater than 0'); + } + + __getNativeAnimationConfig(): {| + damping: number, + initialVelocity: number, + iterations: number, + mass: number, + platformConfig: ?PlatformConfig, + overshootClamping: boolean, + restDisplacementThreshold: number, + restSpeedThreshold: number, + stiffness: number, + toValue: any, + type: $TEMPORARY$string<'spring'>, + |} { + return { + type: 'spring', + overshootClamping: this._overshootClamping, + restDisplacementThreshold: this._restDisplacementThreshold, + restSpeedThreshold: this._restSpeedThreshold, + stiffness: this._stiffness, + damping: this._damping, + mass: this._mass, + initialVelocity: this._initialVelocity ?? this._lastVelocity, + toValue: this._toValue, + iterations: this.__iterations, + platformConfig: this._platformConfig, + }; + } + + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void { + this.__active = true; + this._startPosition = fromValue; + this._lastPosition = this._startPosition; + + this._onUpdate = onUpdate; + this.__onEnd = onEnd; + this._lastTime = Date.now(); + this._frameTime = 0.0; + + if (previousAnimation instanceof SpringAnimation) { + const internalState = previousAnimation.getInternalState(); + this._lastPosition = internalState.lastPosition; + this._lastVelocity = internalState.lastVelocity; + // Set the initial velocity to the last velocity + this._initialVelocity = this._lastVelocity; + this._lastTime = internalState.lastTime; + } + + const start = () => { + if (this._useNativeDriver) { + this.__startNativeAnimation(animatedValue); + } else { + this.onUpdate(); + } + }; + + // If this._delay is more than 0, we start after the timeout. + if (this._delay) { + this._timeout = setTimeout(start, this._delay); + } else { + start(); + } + } + + getInternalState(): Object { + return { + lastPosition: this._lastPosition, + lastVelocity: this._lastVelocity, + lastTime: this._lastTime, + }; + } + + /** + * This spring model is based off of a damped harmonic oscillator + * (https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). + * + * We use the closed form of the second order differential equation: + * + * x'' + (2ζ⍵_0)x' + ⍵^2x = 0 + * + * where + * ⍵_0 = √(k / m) (undamped angular frequency of the oscillator), + * ζ = c / 2√mk (damping ratio), + * c = damping constant + * k = stiffness + * m = mass + * + * The derivation of the closed form is described in detail here: + * http://planetmath.org/sites/default/files/texpdf/39745.pdf + * + * This algorithm happens to match the algorithm used by CASpringAnimation, + * a QuartzCore (iOS) API that creates spring animations. + */ + onUpdate(): void { + // If for some reason we lost a lot of frames (e.g. process large payload or + // stopped in the debugger), we only advance by 4 frames worth of + // computation and will continue on the next frame. It's better to have it + // running at faster speed than jumping to the end. + const MAX_STEPS = 64; + let now = Date.now(); + if (now > this._lastTime + MAX_STEPS) { + now = this._lastTime + MAX_STEPS; + } + + const deltaTime = (now - this._lastTime) / 1000; + this._frameTime += deltaTime; + + const c: number = this._damping; + const m: number = this._mass; + const k: number = this._stiffness; + const v0: number = -this._initialVelocity; + + const zeta = c / (2 * Math.sqrt(k * m)); // damping ratio + const omega0 = Math.sqrt(k / m); // undamped angular frequency of the oscillator (rad/ms) + const omega1 = omega0 * Math.sqrt(1.0 - zeta * zeta); // exponential decay + const x0 = this._toValue - this._startPosition; // calculate the oscillation from x0 = 1 to x = 0 + + let position = 0.0; + let velocity = 0.0; + const t = this._frameTime; + if (zeta < 1) { + // Under damped + const envelope = Math.exp(-zeta * omega0 * t); + position = + this._toValue - + envelope * + (((v0 + zeta * omega0 * x0) / omega1) * Math.sin(omega1 * t) + + x0 * Math.cos(omega1 * t)); + // This looks crazy -- it's actually just the derivative of the + // oscillation function + velocity = + zeta * + omega0 * + envelope * + ((Math.sin(omega1 * t) * (v0 + zeta * omega0 * x0)) / omega1 + + x0 * Math.cos(omega1 * t)) - + envelope * + (Math.cos(omega1 * t) * (v0 + zeta * omega0 * x0) - + omega1 * x0 * Math.sin(omega1 * t)); + } else { + // Critically damped + const envelope = Math.exp(-omega0 * t); + position = this._toValue - envelope * (x0 + (v0 + omega0 * x0) * t); + velocity = + envelope * (v0 * (t * omega0 - 1) + t * x0 * (omega0 * omega0)); + } + + this._lastTime = now; + this._lastPosition = position; + this._lastVelocity = velocity; + + this._onUpdate(position); + if (!this.__active) { + // a listener might have stopped us in _onUpdate + return; + } + + // Conditions for stopping the spring animation + let isOvershooting = false; + if (this._overshootClamping && this._stiffness !== 0) { + if (this._startPosition < this._toValue) { + isOvershooting = position > this._toValue; + } else { + isOvershooting = position < this._toValue; + } + } + const isVelocity = Math.abs(velocity) <= this._restSpeedThreshold; + let isDisplacement = true; + if (this._stiffness !== 0) { + isDisplacement = + Math.abs(this._toValue - position) <= this._restDisplacementThreshold; + } + + if (isOvershooting || (isVelocity && isDisplacement)) { + if (this._stiffness !== 0) { + // Ensure that we end up with a round value + this._lastPosition = this._toValue; + this._lastVelocity = 0; + this._onUpdate(this._toValue); + } + + this.__debouncedOnEnd({finished: true}); + return; + } + // $FlowFixMe[method-unbinding] added when improving typing for this parameters + this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); + } + + stop(): void { + super.stop(); + this.__active = false; + clearTimeout(this._timeout); + global.cancelAnimationFrame(this._animationFrame); + this.__debouncedOnEnd({finished: false}); + } +} From 963989eeee6ab1cfa42bd780890015c8d6c28a4c Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Tue, 10 Jan 2023 12:03:50 -0800 Subject: [PATCH 2/2] update license --- ci/licenses.sh | 2 +- ci/licenses_golden/excluded_files | 1 + ci/licenses_golden/licenses_flutter | 29 ++++++++++++++++++- ci/licenses_golden/tool_signature | 2 +- sky/packages/sky_engine/LICENSE | 22 ++++++++++++++ .../LICENSE.txt => spring_animation/LICENSE} | 0 .../Animated/animations/SpringAnimation.js | 0 third_party/spring_animation/README.md | 5 ++++ tools/licenses/lib/patterns.dart | 13 +++++++++ 9 files changed, 71 insertions(+), 3 deletions(-) rename third_party/{react-native/LICENSE.txt => spring_animation/LICENSE} (100%) rename third_party/{react-native => spring_animation}/Libraries/Animated/animations/SpringAnimation.js (100%) create mode 100644 third_party/spring_animation/README.md diff --git a/ci/licenses.sh b/ci/licenses.sh index 90053c9e74f17..448013a7b034e 100755 --- a/ci/licenses.sh +++ b/ci/licenses.sh @@ -149,7 +149,7 @@ function verify_licenses() ( local actualLicenseCount actualLicenseCount="$(tail -n 1 flutter/ci/licenses_golden/licenses_flutter | tr -dc '0-9')" - local expectedLicenseCount=19 # When changing this number: Update the error message below as well describing the newly expected license types. + local expectedLicenseCount=20 # When changing this number: Update the error message below as well describing the newly expected license types. if [[ $actualLicenseCount -ne $expectedLicenseCount ]]; then echo "=============================== ERROR ===============================" diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index e4ad1cecc2062..eb6a14d67ea93 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -384,6 +384,7 @@ ../../../flutter/third_party/accessibility/gfx/test ../../../flutter/third_party/gn ../../../flutter/third_party/ninja +../../../flutter/third_party/spring_animation/README.md ../../../flutter/third_party/test_shaders ../../../flutter/third_party/tonic/.clang-format ../../../flutter/third_party/tonic/AUTHORS diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 2a31b9f945b4b..baecaa91972f5 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -712,6 +712,33 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ==================================================================================================== +==================================================================================================== +LIBRARY: spring_animation +ORIGIN: ../../../flutter/third_party/spring_animation/Libraries/Animated/animations/SpringAnimation.js + ../../../flutter/third_party/spring_animation/LICENSE +TYPE: LicenseType.mit +FILE: ../../../flutter/third_party/spring_animation/Libraries/Animated/animations/SpringAnimation.js +---------------------------------------------------------------------------------------------------- +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +==================================================================================================== + ==================================================================================================== LIBRARY: accessibility ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_export.h + ../../../flutter/third_party/accessibility/LICENSE @@ -6378,4 +6405,4 @@ use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. ==================================================================================================== -Total license count: 19 +Total license count: 20 diff --git a/ci/licenses_golden/tool_signature b/ci/licenses_golden/tool_signature index ce13f97cfc8ce..af97475b561d3 100644 --- a/ci/licenses_golden/tool_signature +++ b/ci/licenses_golden/tool_signature @@ -1,2 +1,2 @@ -Signature: 3178ef16b4b2174991a8ce7cee53c769 +Signature: 48ebb8e82993ad36a6f8d16f03300065 diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index c6fb809a003d4..a8bb573d9fb1e 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -23719,6 +23719,28 @@ Copyright (c) IBM Corporation, 2000-2016. All rights reserved. This software is made available under the terms of the ICU License -- ICU 1.8.1 and later. -------------------------------------------------------------------------------- +spring_animation + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +-------------------------------------------------------------------------------- harfbuzz Copyright (c) Microsoft Corporation. diff --git a/third_party/react-native/LICENSE.txt b/third_party/spring_animation/LICENSE similarity index 100% rename from third_party/react-native/LICENSE.txt rename to third_party/spring_animation/LICENSE diff --git a/third_party/react-native/Libraries/Animated/animations/SpringAnimation.js b/third_party/spring_animation/Libraries/Animated/animations/SpringAnimation.js similarity index 100% rename from third_party/react-native/Libraries/Animated/animations/SpringAnimation.js rename to third_party/spring_animation/Libraries/Animated/animations/SpringAnimation.js diff --git a/third_party/spring_animation/README.md b/third_party/spring_animation/README.md new file mode 100644 index 0000000000000..3d1731d17fe00 --- /dev/null +++ b/third_party/spring_animation/README.md @@ -0,0 +1,5 @@ +# spring_animation + +This is directly derived from +[Libraries/Animated/animations/SpringAnimation.js](https://github.com/facebook/react-native/blob/494c47360f62761176033a4da359f43b53c2182f/Libraries/Animated/animations/SpringAnimation.js) +as of 2023-01-10, a part of the React Native library. diff --git a/tools/licenses/lib/patterns.dart b/tools/licenses/lib/patterns.dart index 9ca4df84681f5..47f412113c015 100644 --- a/tools/licenses/lib/patterns.dart +++ b/tools/licenses/lib/patterns.dart @@ -490,6 +490,19 @@ final List csReferencesByFilename =