UNPKG

@tamagui/react-native-web-lite

Version:
161 lines (160 loc) 8.55 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: !0 }); }, __copyProps = (to, from, except, desc) => { if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); return to; }; var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod); var SpringAnimation_exports = {}; __export(SpringAnimation_exports, { SpringAnimation: () => SpringAnimation, default: () => SpringAnimation_default }); module.exports = __toCommonJS(SpringAnimation_exports); var import_Animation = require("./Animation.cjs"), import_SpringConfig = require("../SpringConfig.cjs"), import_react_native_web_internals = require("@tamagui/react-native-web-internals"), import_NativeAnimatedHelper = require("../NativeAnimatedHelper.cjs"); class SpringAnimation extends import_Animation.Animation { _overshootClamping; _restDisplacementThreshold; _restSpeedThreshold; _lastVelocity; _startPosition; _lastPosition; _fromValue; _toValue; _stiffness; _damping; _mass; _initialVelocity; _delay; _timeout; _startTime; _lastTime; _frameTime; _onUpdate; _animationFrame; _useNativeDriver; _platformConfig; constructor(config) { if (super(), this._overshootClamping = config.overshootClamping ?? !1, this._restDisplacementThreshold = config.restDisplacementThreshold ?? 1e-3, this._restSpeedThreshold = config.restSpeedThreshold ?? 1e-3, this._initialVelocity = config.velocity ?? 0, this._lastVelocity = config.velocity ?? 0, this._toValue = config.toValue, this._delay = config.delay ?? 0, this._useNativeDriver = (0, import_NativeAnimatedHelper.shouldUseNativeDriver)(config), this._platformConfig = config.platformConfig, this.__isInteraction = config.isInteraction ?? !this._useNativeDriver, this.__iterations = config.iterations ?? 1, config.stiffness !== void 0 || config.damping !== void 0 || config.mass !== void 0) (0, import_react_native_web_internals.invariant)(config.bounciness === void 0 && config.speed === void 0 && config.tension === void 0 && config.friction === void 0, "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 !== void 0 || config.speed !== void 0) { (0, import_react_native_web_internals.invariant)(config.tension === void 0 && config.friction === void 0 && config.stiffness === void 0 && config.damping === void 0 && config.mass === void 0, "You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one"); const springConfig = import_SpringConfig.SpringConfig.fromBouncinessAndSpeed(config.bounciness ?? 8, config.speed ?? 12); this._stiffness = springConfig.stiffness, this._damping = springConfig.damping, this._mass = 1; } else { const springConfig = import_SpringConfig.SpringConfig.fromOrigamiTensionAndFriction(config.tension ?? 40, config.friction ?? 7); this._stiffness = springConfig.stiffness, this._damping = springConfig.damping, this._mass = 1; } (0, import_react_native_web_internals.invariant)(this._stiffness > 0, "Stiffness value must be greater than 0"), (0, import_react_native_web_internals.invariant)(this._damping > 0, "Damping value must be greater than 0"), (0, import_react_native_web_internals.invariant)(this._mass > 0, "Mass value must be greater than 0"); } __getNativeAnimationConfig() { 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, onUpdate, onEnd, previousAnimation, animatedValue) { if (this.__active = !0, this._startPosition = fromValue, this._lastPosition = this._startPosition, this._onUpdate = onUpdate, this.__onEnd = onEnd, this._lastTime = Date.now(), this._frameTime = 0, previousAnimation instanceof SpringAnimation) { const internalState = previousAnimation.getInternalState(); this._lastPosition = internalState.lastPosition, this._lastVelocity = internalState.lastVelocity, this._initialVelocity = this._lastVelocity, this._lastTime = internalState.lastTime; } const start = () => { this._useNativeDriver ? this.__startNativeAnimation(animatedValue) : this.onUpdate(); }; this._delay ? this._timeout = setTimeout(start, this._delay) : start(); } 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. */ onUpdate() { let now = Date.now(); now > this._lastTime + 64 && (now = this._lastTime + 64); const deltaTime = (now - this._lastTime) / 1e3; this._frameTime += deltaTime; const c = this._damping, m = this._mass, k = this._stiffness, v0 = -this._initialVelocity, zeta = c / (2 * Math.sqrt(k * m)), omega0 = Math.sqrt(k / m), omega1 = omega0 * Math.sqrt(1 - zeta * zeta), x0 = this._toValue - this._startPosition; let position = 0, velocity = 0; const t = this._frameTime; if (zeta < 1) { 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)), 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 { 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)); } if (this._lastTime = now, this._lastPosition = position, this._lastVelocity = velocity, this._onUpdate(position), !this.__active) return; let isOvershooting = !1; this._overshootClamping && this._stiffness !== 0 && (this._startPosition < this._toValue ? isOvershooting = position > this._toValue : isOvershooting = position < this._toValue); const isVelocity = Math.abs(velocity) <= this._restSpeedThreshold; let isDisplacement = !0; if (this._stiffness !== 0 && (isDisplacement = Math.abs(this._toValue - position) <= this._restDisplacementThreshold), isOvershooting || isVelocity && isDisplacement) { this._stiffness !== 0 && (this._lastPosition = this._toValue, this._lastVelocity = 0, this._onUpdate(this._toValue)), this.__debouncedOnEnd({ finished: !0 }); return; } this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); } stop() { super.stop(), this.__active = !1, clearTimeout(this._timeout), global.cancelAnimationFrame(this._animationFrame), this.__debouncedOnEnd({ finished: !1 }); } } var SpringAnimation_default = SpringAnimation;