UNPKG

@popmotion/popcorn

Version:

Utility functions for animation and interactions.

976 lines (925 loc) 36.4 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.popcorn = {}))); }(this, (function (exports) { 'use strict'; var zeroPoint = { x: 0, y: 0, z: 0 }; var isNum = function (v) { return typeof v === 'number'; }; var radiansToDegrees = (function (radians) { return (radians * 180) / Math.PI; }); var angle = (function (a, b) { if (b === void 0) { b = zeroPoint; } return radiansToDegrees(Math.atan2(b.y - a.y, b.x - a.x)); }); var applyOffset = (function (from, to) { var hasReceivedFrom = true; if (to === undefined) { to = from; hasReceivedFrom = false; } return function (v) { if (hasReceivedFrom) { return v - from + to; } else { from = v; hasReceivedFrom = true; return to; } }; }); var curryRange = (function (func) { return function (min, max, v) { return (v !== undefined ? func(min, max, v) : function (cv) { return func(min, max, cv); }); }; }); var clamp = function (min, max, v) { return Math.min(Math.max(v, min), max); }; var clamp$1 = curryRange(clamp); var conditional = (function (check, apply) { return function (v) { return check(v) ? apply(v) : v; }; }); var degreesToRadians = (function (degrees) { return (degrees * Math.PI) / 180; }); var isPoint = (function (point) { return point.hasOwnProperty('x') && point.hasOwnProperty('y'); }); var isPoint3D = (function (point) { return isPoint(point) && point.hasOwnProperty('z'); }); var distance1D = function (a, b) { return Math.abs(a - b); }; var distance = (function (a, b) { if (b === void 0) { b = zeroPoint; } if (isNum(a) && isNum(b)) { return distance1D(a, b); } else if (isPoint(a) && isPoint(b)) { var xDelta = distance1D(a.x, b.x); var yDelta = distance1D(a.y, b.y); var zDelta = isPoint3D(a) && isPoint3D(b) ? distance1D(a.z, b.z) : 0; return Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2) + Math.pow(zDelta, 2)); } return 0; }); var progress = (function (from, to, value) { var toFromDifference = to - from; return toFromDifference === 0 ? 1 : (value - from) / toFromDifference; }); var mix = (function (from, to, progress) { return -progress * from + progress * to + from; }); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var __assign$1 = function() { __assign$1 = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign$1.apply(this, arguments); }; var clamp$2 = function (min, max) { return function (v) { return Math.max(Math.min(v, max), min); }; }; var sanitize = function (v) { return (v % 1 ? Number(v.toFixed(5)) : v); }; var floatRegex = /(-)?(\d[\d\.]*)/g; var colorRegex = /(#[0-9a-f]{6}|#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; var singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i; var number = { test: function (v) { return typeof v === 'number'; }, parse: parseFloat, transform: function (v) { return v; } }; var alpha = __assign$1(__assign$1({}, number), { transform: clamp$2(0, 1) }); var scale = __assign$1(__assign$1({}, number), { default: 1 }); var createUnitType = function (unit) { return ({ test: function (v) { return typeof v === 'string' && v.endsWith(unit) && v.split(' ').length === 1; }, parse: parseFloat, transform: function (v) { return "" + v + unit; } }); }; var percent = createUnitType('%'); var progressPercentage = __assign$1(__assign$1({}, percent), { parse: function (v) { return percent.parse(v) / 100; }, transform: function (v) { return percent.transform(v * 100); } }); var getValueFromFunctionString = function (value) { return value.substring(value.indexOf('(') + 1, value.lastIndexOf(')')); }; var clampRgbUnit = clamp$2(0, 255); var isRgba = function (v) { return v.red !== undefined; }; var isHsla = function (v) { return v.hue !== undefined; }; var splitColorValues = function (terms) { return function (v) { if (typeof v !== 'string') return v; var values = {}; var valuesArray = getValueFromFunctionString(v).split(/,\s*/); for (var i = 0; i < 4; i++) { values[terms[i]] = valuesArray[i] !== undefined ? parseFloat(valuesArray[i]) : 1; } return values; }; }; var rgbaTemplate = function (_a) { var red = _a.red, green = _a.green, blue = _a.blue, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b; return "rgba(" + red + ", " + green + ", " + blue + ", " + alpha$$1 + ")"; }; var hslaTemplate = function (_a) { var hue = _a.hue, saturation = _a.saturation, lightness = _a.lightness, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b; return "hsla(" + hue + ", " + saturation + ", " + lightness + ", " + alpha$$1 + ")"; }; var rgbUnit = __assign$1(__assign$1({}, number), { transform: function (v) { return Math.round(clampRgbUnit(v)); } }); function isColorString(color, colorType) { return color.startsWith(colorType) && singleColorRegex.test(color); } var rgba = { test: function (v) { return (typeof v === 'string' ? isColorString(v, 'rgb') : isRgba(v)); }, parse: splitColorValues(['red', 'green', 'blue', 'alpha']), transform: function (_a) { var red = _a.red, green = _a.green, blue = _a.blue, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b; return rgbaTemplate({ red: rgbUnit.transform(red), green: rgbUnit.transform(green), blue: rgbUnit.transform(blue), alpha: sanitize(alpha.transform(alpha$$1)) }); } }; var hsla = { test: function (v) { return (typeof v === 'string' ? isColorString(v, 'hsl') : isHsla(v)); }, parse: splitColorValues(['hue', 'saturation', 'lightness', 'alpha']), transform: function (_a) { var hue = _a.hue, saturation = _a.saturation, lightness = _a.lightness, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b; return hslaTemplate({ hue: Math.round(hue), saturation: percent.transform(sanitize(saturation)), lightness: percent.transform(sanitize(lightness)), alpha: sanitize(alpha.transform(alpha$$1)) }); } }; var hex = __assign$1(__assign$1({}, rgba), { test: function (v) { return typeof v === 'string' && isColorString(v, '#'); }, parse: function (v) { var r = ''; var g = ''; var b = ''; if (v.length > 4) { r = v.substr(1, 2); g = v.substr(3, 2); b = v.substr(5, 2); } else { r = v.substr(1, 1); g = v.substr(2, 1); b = v.substr(3, 1); r += r; g += g; b += b; } return { red: parseInt(r, 16), green: parseInt(g, 16), blue: parseInt(b, 16), alpha: 1 }; } }); var color = { test: function (v) { return (typeof v === 'string' && singleColorRegex.test(v)) || isRgba(v) || isHsla(v); }, parse: function (v) { if (rgba.test(v)) { return rgba.parse(v); } else if (hsla.test(v)) { return hsla.parse(v); } else if (hex.test(v)) { return hex.parse(v); } return v; }, transform: function (v) { if (isRgba(v)) { return rgba.transform(v); } else if (isHsla(v)) { return hsla.transform(v); } return v; } }; var COLOR_TOKEN = '${c}'; var NUMBER_TOKEN = '${n}'; var convertNumbersToZero = function (v) { return typeof v === 'number' ? 0 : v; }; var complex = { test: function (v) { if (typeof v !== 'string' || !isNaN(v)) return false; var numValues = 0; var foundNumbers = v.match(floatRegex); var foundColors = v.match(colorRegex); if (foundNumbers) numValues += foundNumbers.length; if (foundColors) numValues += foundColors.length; return numValues > 0; }, parse: function (v) { var input = v; var parsed = []; var foundColors = input.match(colorRegex); if (foundColors) { input = input.replace(colorRegex, COLOR_TOKEN); parsed.push.apply(parsed, foundColors.map(color.parse)); } var foundNumbers = input.match(floatRegex); if (foundNumbers) { parsed.push.apply(parsed, foundNumbers.map(number.parse)); } return parsed; }, createTransformer: function (prop) { var template = prop; var token = 0; var foundColors = prop.match(colorRegex); var numColors = foundColors ? foundColors.length : 0; if (foundColors) { for (var i = 0; i < numColors; i++) { template = template.replace(foundColors[i], COLOR_TOKEN); token++; } } var foundNumbers = template.match(floatRegex); var numNumbers = foundNumbers ? foundNumbers.length : 0; if (foundNumbers) { for (var i = 0; i < numNumbers; i++) { template = template.replace(foundNumbers[i], NUMBER_TOKEN); token++; } } return function (v) { var output = template; for (var i = 0; i < token; i++) { output = output.replace(i < numColors ? COLOR_TOKEN : NUMBER_TOKEN, i < numColors ? color.transform(v[i]) : sanitize(v[i])); } return output; }; }, getAnimatableNone: function (target) { var parsedTarget = complex.parse(target); var targetTransformer = complex.createTransformer(target); return targetTransformer(parsedTarget.map(convertNumbersToZero)); } }; var invariant = function () { }; if (process.env.NODE_ENV !== 'production') { invariant = function (check, message) { if (!check) { throw new Error(message); } }; } var mixLinearColor = function (from, to, v) { var fromExpo = from * from; var toExpo = to * to; return Math.sqrt(Math.max(0, v * (toExpo - fromExpo) + fromExpo)); }; var colorTypes = [hex, rgba, hsla]; var getColorType = function (v) { return colorTypes.find(function (type) { return type.test(v); }); }; var notAnimatable = function (color$$1) { return "'" + color$$1 + "' is not an animatable color. Use the equivalent color code instead."; }; var mixColor = (function (from, to) { var fromColorType = getColorType(from); var toColorType = getColorType(to); invariant(!!fromColorType, notAnimatable(from)); invariant(!!toColorType, notAnimatable(to)); invariant(fromColorType.transform === toColorType.transform, 'Both colors must be hex/RGBA, OR both must be HSLA.'); var fromColor = fromColorType.parse(from); var toColor = toColorType.parse(to); var blended = __assign({}, fromColor); var mixFunc = fromColorType === hsla ? mix : mixLinearColor; return function (v) { for (var key in blended) { if (key !== 'alpha') { blended[key] = mixFunc(fromColor[key], toColor[key], v); } } blended.alpha = mix(fromColor.alpha, toColor.alpha, v); return fromColorType.transform(blended); }; }); var combineFunctions = function (a, b) { return function (v) { return b(a(v)); }; }; var pipe = (function () { var transformers = []; for (var _i = 0; _i < arguments.length; _i++) { transformers[_i] = arguments[_i]; } return transformers.reduce(combineFunctions); }); function getMixer(origin, target) { if (isNum(origin)) { return function (v) { return mix(origin, target, v); }; } else if (color.test(origin)) { return mixColor(origin, target); } else { return mixComplex(origin, target); } } var mixArray = function (from, to) { var output = from.slice(); var numValues = output.length; var blendValue = from.map(function (fromThis, i) { return getMixer(fromThis, to[i]); }); return function (v) { for (var i = 0; i < numValues; i++) { output[i] = blendValue[i](v); } return output; }; }; var mixObject = function (origin, target) { var output = __assign({}, origin, target); var blendValue = {}; for (var key in output) { if (origin[key] !== undefined && target[key] !== undefined) { blendValue[key] = getMixer(origin[key], target[key]); } } return function (v) { for (var key in blendValue) { output[key] = blendValue[key](v); } return output; }; }; function analyse(value) { var parsed = complex.parse(value); var numValues = parsed.length; var numNumbers = 0; var numRGB = 0; var numHSL = 0; for (var i = 0; i < numValues; i++) { if (numNumbers || typeof parsed[i] === 'number') { numNumbers++; } else { if (parsed[i].hue !== undefined) { numHSL++; } else { numRGB++; } } } return { parsed: parsed, numNumbers: numNumbers, numRGB: numRGB, numHSL: numHSL }; } var mixComplex = function (origin, target) { var template = complex.createTransformer(target); var originStats = analyse(origin); var targetStats = analyse(target); invariant(originStats.numHSL === targetStats.numHSL && originStats.numRGB === targetStats.numRGB && originStats.numNumbers >= targetStats.numNumbers, "Complex values '" + origin + "' and '" + target + "' too different to mix. Ensure all colors are of the same type."); return pipe(mixArray(originStats.parsed, targetStats.parsed), template); }; var mixNumber = function (from, to) { return function (p) { return mix(from, to, p); }; }; function detectMixerFactory(v) { if (typeof v === 'number') { return mixNumber; } else if (typeof v === 'string') { if (color.test(v)) { return mixColor; } else { return mixComplex; } } else if (Array.isArray(v)) { return mixArray; } else if (typeof v === 'object') { return mixObject; } } function createMixers(output, ease, customMixer) { var mixers = []; var mixerFactory = customMixer || detectMixerFactory(output[0]); var numMixers = output.length - 1; for (var i = 0; i < numMixers; i++) { var mixer = mixerFactory(output[i], output[i + 1]); if (ease) { var easingFunction = Array.isArray(ease) ? ease[i] : ease; mixer = pipe(easingFunction, mixer); } mixers.push(mixer); } return mixers; } function fastInterpolate(_a, _b) { var from = _a[0], to = _a[1]; var mixer = _b[0]; return function (v) { return mixer(progress(from, to, v)); }; } function slowInterpolate(input, mixers) { var inputLength = input.length; var lastInputIndex = inputLength - 1; return function (v) { var mixerIndex = 0; var foundMixerIndex = false; if (v <= input[0]) { foundMixerIndex = true; } else if (v >= input[lastInputIndex]) { mixerIndex = lastInputIndex - 1; foundMixerIndex = true; } if (!foundMixerIndex) { var i = 1; for (; i < inputLength; i++) { if (input[i] > v || i === lastInputIndex) { break; } } mixerIndex = i - 1; } var progressInRange = progress(input[mixerIndex], input[mixerIndex + 1], v); return mixers[mixerIndex](progressInRange); }; } function interpolate(input, output, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.clamp, clamp = _c === void 0 ? true : _c, ease = _b.ease, mixer = _b.mixer; var inputLength = input.length; invariant(inputLength === output.length, 'Both input and output ranges must be the same length'); invariant(!ease || !Array.isArray(ease) || ease.length === inputLength - 1, 'Array of easing functions must be of length `input.length - 1`, as it applies to the transitions **between** the defined values.'); if (input[0] > input[inputLength - 1]) { input = [].concat(input); output = [].concat(output); input.reverse(); output.reverse(); } var mixers = createMixers(output, ease, mixer); var interpolator = inputLength === 2 ? fastInterpolate(input, mixers) : slowInterpolate(input, mixers); return clamp ? pipe(clamp$1(input[0], input[inputLength - 1]), interpolator) : interpolator; } var pointFromVector = (function (origin, angle, distance) { angle = degreesToRadians(angle); return { x: distance * Math.cos(angle) + origin.x, y: distance * Math.sin(angle) + origin.y }; }); var toDecimal = (function (num, precision) { if (precision === void 0) { precision = 2; } precision = Math.pow(10, precision); return Math.round(num * precision) / precision; }); var smoothFrame = (function (prevValue, nextValue, duration, smoothing) { if (smoothing === void 0) { smoothing = 0; } return toDecimal(prevValue + (duration * (nextValue - prevValue)) / Math.max(smoothing, duration)); }); var HEY_LISTEN = 'Hey, listen! '; var invariant$1 = function () { }; if (process.env.NODE_ENV !== 'production') { invariant$1 = function (check, message) { if (!check) { throw new Error(HEY_LISTEN.toUpperCase() + message); } }; } var prevTime = 0; var onNextFrame = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined ? function (callback) { return window.requestAnimationFrame(callback); } : function (callback) { var timestamp = Date.now(); var timeToCall = Math.max(0, 16.7 - (timestamp - prevTime)); prevTime = timestamp + timeToCall; setTimeout(function () { return callback(prevTime); }, timeToCall); }; var createStep = (function (setRunNextFrame) { var processToRun = []; var processToRunNextFrame = []; var numThisFrame = 0; var isProcessing = false; var i = 0; var cancelled = new WeakSet(); var toKeepAlive = new WeakSet(); var renderStep = { cancel: function (process) { var indexOfCallback = processToRunNextFrame.indexOf(process); cancelled.add(process); if (indexOfCallback !== -1) { processToRunNextFrame.splice(indexOfCallback, 1); } }, process: function (frame) { var _a; isProcessing = true; _a = [ processToRunNextFrame, processToRun ], processToRun = _a[0], processToRunNextFrame = _a[1]; processToRunNextFrame.length = 0; numThisFrame = processToRun.length; if (numThisFrame) { var process_1; for (i = 0; i < numThisFrame; i++) { process_1 = processToRun[i]; process_1(frame); if (toKeepAlive.has(process_1) === true && !cancelled.has(process_1)) { renderStep.schedule(process_1); setRunNextFrame(true); } } } isProcessing = false; }, schedule: function (process, keepAlive, immediate) { if (keepAlive === void 0) { keepAlive = false; } if (immediate === void 0) { immediate = false; } invariant$1(typeof process === 'function', 'Argument must be a function'); var addToCurrentBuffer = immediate && isProcessing; var buffer = addToCurrentBuffer ? processToRun : processToRunNextFrame; cancelled.delete(process); if (keepAlive) toKeepAlive.add(process); if (buffer.indexOf(process) === -1) { buffer.push(process); if (addToCurrentBuffer) numThisFrame = processToRun.length; } } }; return renderStep; }); var StepId; (function (StepId) { StepId["Read"] = "read"; StepId["Update"] = "update"; StepId["Render"] = "render"; StepId["PostRender"] = "postRender"; StepId["FixedUpdate"] = "fixedUpdate"; })(StepId || (StepId = {})); var maxElapsed = 40; var defaultElapsed = (1 / 60) * 1000; var useDefaultElapsed = true; var willRunNextFrame = false; var isProcessing = false; var frame = { delta: 0, timestamp: 0 }; var stepsOrder = [ StepId.Read, StepId.Update, StepId.Render, StepId.PostRender ]; var setWillRunNextFrame = function (willRun) { return (willRunNextFrame = willRun); }; var _a = stepsOrder.reduce(function (acc, key) { var step = createStep(setWillRunNextFrame); acc.sync[key] = function (process, keepAlive, immediate) { if (keepAlive === void 0) { keepAlive = false; } if (immediate === void 0) { immediate = false; } if (!willRunNextFrame) startLoop(); step.schedule(process, keepAlive, immediate); return process; }; acc.cancelSync[key] = function (process) { return step.cancel(process); }; acc.steps[key] = step; return acc; }, { steps: {}, sync: {}, cancelSync: {} }), steps = _a.steps, sync = _a.sync, cancelSync = _a.cancelSync; var processStep = function (stepId) { return steps[stepId].process(frame); }; var processFrame = function (timestamp) { willRunNextFrame = false; frame.delta = useDefaultElapsed ? defaultElapsed : Math.max(Math.min(timestamp - frame.timestamp, maxElapsed), 1); if (!useDefaultElapsed) defaultElapsed = frame.delta; frame.timestamp = timestamp; isProcessing = true; stepsOrder.forEach(processStep); isProcessing = false; if (willRunNextFrame) { useDefaultElapsed = false; onNextFrame(processFrame); } }; var startLoop = function () { willRunNextFrame = true; useDefaultElapsed = true; if (!isProcessing) onNextFrame(processFrame); }; var getFrameData = function () { return frame; }; var smooth = (function (strength) { if (strength === void 0) { strength = 50; } var previousValue = 0; var lastUpdated = 0; return function (v) { var currentFramestamp = getFrameData().timestamp; var timeDelta = currentFramestamp !== lastUpdated ? currentFramestamp - lastUpdated : 0; var newValue = timeDelta ? smoothFrame(previousValue, v, timeDelta, strength) : previousValue; lastUpdated = currentFramestamp; previousValue = newValue; return newValue; }; }); var snap = (function (points) { if (typeof points === 'number') { return function (v) { return Math.round(v / points) * points; }; } else { var i_1 = 0; var numPoints_1 = points.length; return function (v) { var lastDistance = Math.abs(points[0] - v); for (i_1 = 1; i_1 < numPoints_1; i_1++) { var point = points[i_1]; var distance = Math.abs(point - v); if (distance === 0) return point; if (distance > lastDistance) return points[i_1 - 1]; if (i_1 === numPoints_1 - 1) return point; lastDistance = distance; } }; } }); var identity = function (v) { return v; }; var springForce = function (alterDisplacement) { if (alterDisplacement === void 0) { alterDisplacement = identity; } return curryRange(function (constant, origin, v) { var displacement = origin - v; var springModifiedDisplacement = -(0 - constant + 1) * (0 - alterDisplacement(Math.abs(displacement))); return displacement <= 0 ? origin + springModifiedDisplacement : origin - springModifiedDisplacement; }); }; var springForceLinear = springForce(); var springForceExpo = springForce(Math.sqrt); var velocityPerFrame = (function (xps, frameDuration) { return isNum(xps) ? xps / (1000 / frameDuration) : 0; }); var velocityPerSecond = (function (velocity, frameDuration) { return frameDuration ? velocity * (1000 / frameDuration) : 0; }); var wrap = function (min, max, v) { var rangeSize = max - min; return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min; }; var wrap$1 = curryRange(wrap); var clampProgress = clamp$1(0, 1); var steps$1 = (function (steps, direction) { if (direction === void 0) { direction = 'end'; } return function (progress) { progress = direction === 'end' ? Math.min(progress, 0.999) : Math.max(progress, 0.001); var expanded = progress * steps; var rounded = direction === 'end' ? Math.floor(expanded) : Math.ceil(expanded); return clampProgress(rounded / steps); }; }); var DEFAULT_OVERSHOOT_STRENGTH = 1.525; var reversed = function (easing) { return function (p) { return 1 - easing(1 - p); }; }; var mirrored = function (easing) { return function (p) { return p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2; }; }; var createExpoIn = function (power) { return function (p) { return Math.pow(p, power); }; }; var createBackIn = function (power) { return function (p) { return p * p * ((power + 1) * p - power); }; }; var createAnticipateEasing = function (power) { var backEasing = createBackIn(power); return function (p) { return (p *= 2) < 1 ? 0.5 * backEasing(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1))); }; }; var linear = function (p) { return p; }; var easeIn = /*#__PURE__*/createExpoIn(2); var easeOut = /*#__PURE__*/reversed(easeIn); var easeInOut = /*#__PURE__*/mirrored(easeIn); var circIn = function (p) { return 1 - Math.sin(Math.acos(p)); }; var circOut = /*#__PURE__*/reversed(circIn); var circInOut = /*#__PURE__*/mirrored(circOut); var backIn = /*#__PURE__*/createBackIn(DEFAULT_OVERSHOOT_STRENGTH); var backOut = /*#__PURE__*/reversed(backIn); var backInOut = /*#__PURE__*/mirrored(backIn); var anticipate = /*#__PURE__*/createAnticipateEasing(DEFAULT_OVERSHOOT_STRENGTH); var NEWTON_ITERATIONS = 8; var NEWTON_MIN_SLOPE = 0.001; var SUBDIVISION_PRECISION = 0.0000001; var SUBDIVISION_MAX_ITERATIONS = 10; var K_SPLINE_TABLE_SIZE = 11; var K_SAMPLE_STEP_SIZE = 1.0 / (K_SPLINE_TABLE_SIZE - 1.0); var FLOAT_32_SUPPORTED = typeof Float32Array !== 'undefined'; var a = function (a1, a2) { return 1.0 - 3.0 * a2 + 3.0 * a1; }; var b = function (a1, a2) { return 3.0 * a2 - 6.0 * a1; }; var c = function (a1) { return 3.0 * a1; }; var getSlope = function (t, a1, a2) { return 3.0 * a(a1, a2) * t * t + 2.0 * b(a1, a2) * t + c(a1); }; var calcBezier = function (t, a1, a2) { return ((a(a1, a2) * t + b(a1, a2)) * t + c(a1)) * t; }; function cubicBezier(mX1, mY1, mX2, mY2) { var sampleValues = FLOAT_32_SUPPORTED ? new Float32Array(K_SPLINE_TABLE_SIZE) : new Array(K_SPLINE_TABLE_SIZE); var binarySubdivide = function (aX, aA, aB) { var i = 0; var currentX; var currentT; do { currentT = aA + (aB - aA) / 2.0; currentX = calcBezier(currentT, mX1, mX2) - aX; if (currentX > 0.0) { aB = currentT; } else { aA = currentT; } } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); return currentT; }; var newtonRaphsonIterate = function (aX, aGuessT) { var i = 0; var currentSlope = 0; var currentX; for (; i < NEWTON_ITERATIONS; ++i) { currentSlope = getSlope(aGuessT, mX1, mX2); if (currentSlope === 0.0) { return aGuessT; } currentX = calcBezier(aGuessT, mX1, mX2) - aX; aGuessT -= currentX / currentSlope; } return aGuessT; }; var calcSampleValues = function () { for (var i = 0; i < K_SPLINE_TABLE_SIZE; ++i) { sampleValues[i] = calcBezier(i * K_SAMPLE_STEP_SIZE, mX1, mX2); } }; var getTForX = function (aX) { var intervalStart = 0.0; var currentSample = 1; var lastSample = K_SPLINE_TABLE_SIZE - 1; var dist = 0.0; var guessForT = 0.0; var initialSlope = 0.0; for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { intervalStart += K_SAMPLE_STEP_SIZE; } --currentSample; dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); guessForT = intervalStart + dist * K_SAMPLE_STEP_SIZE; initialSlope = getSlope(guessForT, mX1, mX2); if (initialSlope >= NEWTON_MIN_SLOPE) { return newtonRaphsonIterate(aX, guessForT); } else if (initialSlope === 0.0) { return guessForT; } else { return binarySubdivide(aX, intervalStart, intervalStart + K_SAMPLE_STEP_SIZE); } }; calcSampleValues(); var resolver = function (aX) { var returnValue; if (mX1 === mY1 && mX2 === mY2) { returnValue = aX; } else if (aX === 0) { returnValue = 0; } else if (aX === 1) { returnValue = 1; } else { returnValue = calcBezier(getTForX(aX), mY1, mY2); } return returnValue; }; return resolver; } exports.angle = angle; exports.applyOffset = applyOffset; exports.clamp = clamp$1; exports.conditional = conditional; exports.degreesToRadians = degreesToRadians; exports.distance = distance; exports.interpolate = interpolate; exports.isPoint = isPoint; exports.isPoint3D = isPoint3D; exports.mix = mix; exports.mixArray = mixArray; exports.mixColor = mixColor; exports.mixComplex = mixComplex; exports.mixObject = mixObject; exports.pipe = pipe; exports.pointFromVector = pointFromVector; exports.progress = progress; exports.radiansToDegrees = radiansToDegrees; exports.smooth = smooth; exports.smoothFrame = smoothFrame; exports.snap = snap; exports.springForce = springForce; exports.springForceExpo = springForceExpo; exports.springForceLinear = springForceLinear; exports.steps = steps$1; exports.toDecimal = toDecimal; exports.velocityPerFrame = velocityPerFrame; exports.velocityPerSecond = velocityPerSecond; exports.wrap = wrap$1; exports.createAnticipateEasing = createAnticipateEasing; exports.createBackIn = createBackIn; exports.createExpoIn = createExpoIn; exports.cubicBezier = cubicBezier; exports.linear = linear; exports.easeIn = easeIn; exports.easeOut = easeOut; exports.easeInOut = easeInOut; exports.circIn = circIn; exports.circOut = circOut; exports.circInOut = circInOut; exports.backIn = backIn; exports.backOut = backOut; exports.backInOut = backInOut; exports.anticipate = anticipate; exports.reversed = reversed; exports.mirrored = mirrored; Object.defineProperty(exports, '__esModule', { value: true }); })));