UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

273 lines (220 loc) 11.3 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * * @format */ 'use strict'; function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } import AnimatedValue from '../nodes/AnimatedValue'; import AnimatedValueXY from '../nodes/AnimatedValueXY'; import AnimatedInterpolation from '../nodes/AnimatedInterpolation'; import Animation from './Animation'; import SpringConfig from '../SpringConfig'; import invariant from 'fbjs/lib/invariant'; import { shouldUseNativeDriver } from '../NativeAnimatedHelper'; var SpringAnimation = /*#__PURE__*/function (_Animation) { _inheritsLoose(SpringAnimation, _Animation); function SpringAnimation(config) { var _config$overshootClam, _config$restDisplacem, _config$restSpeedThre, _config$velocity, _config$velocity2, _config$delay, _config$isInteraction, _config$iterations; var _this; _this = _Animation.call(this) || this; _this._overshootClamping = (_config$overshootClam = config.overshootClamping) !== null && _config$overshootClam !== void 0 ? _config$overshootClam : false; _this._restDisplacementThreshold = (_config$restDisplacem = config.restDisplacementThreshold) !== null && _config$restDisplacem !== void 0 ? _config$restDisplacem : 0.001; _this._restSpeedThreshold = (_config$restSpeedThre = config.restSpeedThreshold) !== null && _config$restSpeedThre !== void 0 ? _config$restSpeedThre : 0.001; _this._initialVelocity = (_config$velocity = config.velocity) !== null && _config$velocity !== void 0 ? _config$velocity : 0; _this._lastVelocity = (_config$velocity2 = config.velocity) !== null && _config$velocity2 !== void 0 ? _config$velocity2 : 0; _this._toValue = config.toValue; _this._delay = (_config$delay = config.delay) !== null && _config$delay !== void 0 ? _config$delay : 0; _this._useNativeDriver = shouldUseNativeDriver(config); _this.__isInteraction = (_config$isInteraction = config.isInteraction) !== null && _config$isInteraction !== void 0 ? _config$isInteraction : !_this._useNativeDriver; _this.__iterations = (_config$iterations = config.iterations) !== null && _config$iterations !== void 0 ? _config$iterations : 1; if (config.stiffness !== undefined || config.damping !== undefined || config.mass !== undefined) { var _config$stiffness, _config$damping, _config$mass; 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 = config.stiffness) !== null && _config$stiffness !== void 0 ? _config$stiffness : 100; _this._damping = (_config$damping = config.damping) !== null && _config$damping !== void 0 ? _config$damping : 10; _this._mass = (_config$mass = config.mass) !== null && _config$mass !== void 0 ? _config$mass : 1; } else if (config.bounciness !== undefined || config.speed !== undefined) { var _config$bounciness, _config$speed; // 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'); var springConfig = SpringConfig.fromBouncinessAndSpeed((_config$bounciness = config.bounciness) !== null && _config$bounciness !== void 0 ? _config$bounciness : 8, (_config$speed = config.speed) !== null && _config$speed !== void 0 ? _config$speed : 12); _this._stiffness = springConfig.stiffness; _this._damping = springConfig.damping; _this._mass = 1; } else { var _config$tension, _config$friction; // Convert the origami tension/friction values to stiffness/damping // We assume mass is 1. var _springConfig = SpringConfig.fromOrigamiTensionAndFriction((_config$tension = config.tension) !== null && _config$tension !== void 0 ? _config$tension : 40, (_config$friction = config.friction) !== null && _config$friction !== void 0 ? _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'); return _this; } var _proto = SpringAnimation.prototype; _proto.__getNativeAnimationConfig = function __getNativeAnimationConfig() { var _this$_initialVelocit; return { type: 'spring', overshootClamping: this._overshootClamping, restDisplacementThreshold: this._restDisplacementThreshold, restSpeedThreshold: this._restSpeedThreshold, stiffness: this._stiffness, damping: this._damping, mass: this._mass, initialVelocity: (_this$_initialVelocit = this._initialVelocity) !== null && _this$_initialVelocit !== void 0 ? _this$_initialVelocit : this._lastVelocity, toValue: this._toValue, iterations: this.__iterations }; }; _proto.start = function start(fromValue, onUpdate, onEnd, previousAnimation, animatedValue) { var _this2 = this; 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) { var 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; } var start = function start() { if (_this2._useNativeDriver) { _this2.__startNativeAnimation(animatedValue); } else { _this2.onUpdate(); } }; // If this._delay is more than 0, we start after the timeout. if (this._delay) { this._timeout = setTimeout(start, this._delay); } else { start(); } }; _proto.getInternalState = function getInternalState() { 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. */ ; _proto.onUpdate = function onUpdate() { // 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. var MAX_STEPS = 64; var now = Date.now(); if (now > this._lastTime + MAX_STEPS) { now = this._lastTime + MAX_STEPS; } var deltaTime = (now - this._lastTime) / 1000; this._frameTime += deltaTime; var c = this._damping; var m = this._mass; var k = this._stiffness; var v0 = -this._initialVelocity; var zeta = c / (2 * Math.sqrt(k * m)); // damping ratio var omega0 = Math.sqrt(k / m); // undamped angular frequency of the oscillator (rad/ms) var omega1 = omega0 * Math.sqrt(1.0 - zeta * zeta); // exponential decay var x0 = this._toValue - this._startPosition; // calculate the oscillation from x0 = 1 to x = 0 var position = 0.0; var velocity = 0.0; var t = this._frameTime; if (zeta < 1) { // Under damped var 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 var _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 var isOvershooting = false; if (this._overshootClamping && this._stiffness !== 0) { if (this._startPosition < this._toValue) { isOvershooting = position > this._toValue; } else { isOvershooting = position < this._toValue; } } var isVelocity = Math.abs(velocity) <= this._restSpeedThreshold; var 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; } this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); }; _proto.stop = function stop() { _Animation.prototype.stop.call(this); this.__active = false; clearTimeout(this._timeout); global.cancelAnimationFrame(this._animationFrame); this.__debouncedOnEnd({ finished: false }); }; return SpringAnimation; }(Animation); export default SpringAnimation;