UNPKG

redshift

Version:

A JavaScript UX framework. Handles animation, UI physics and user input tracking.

208 lines (162 loc) 6.72 kB
/* Easing functions ---------------------------------------- Generates and provides easing functions based on baseFunction definitions A call to easingFunction.get('functionName') returns a function that can be passed: @param [number]: Progress 0-1 @param [number] (optional): Amp modifier, only accepted in some easing functions and is used to adjust overall strength @return [number]: Eased progress We can generate new functions by sending an easing function through easingFunction.extend(name, method). Which will make nameIn, nameOut and nameInOut functions available to use. Easing functions from Robert Penner http://www.robertpenner.com/easing/ Bezier curve interpretor created from Gaëtan Renaudeau's original BezierEasing https://github.com/gre/bezier-easing/blob/master/index.js https://github.com/gre/bezier-easing/blob/master/LICENSE */ "use strict"; var calc = require('./calc.js'), Bezier = require('../types/bezier.js'), // Constants INVALID_EASING = ": Not defined", EASE_IN = 'In', EASE_OUT = 'Out', EASE_IN_OUT = EASE_IN + EASE_OUT, // Base power ease names powerEasing = ['ease', 'cubic', 'quart', 'quint'], // Generate easing function with provided power generatePowerEasing = function (power) { return function (progress) { return Math.pow(progress, power); } }, /* Each of these base functions is an easeIn On init, we use EasingFunction.mirror and .reverse to generate easeInOut and easeOut functions respectively. */ baseEasing = { circ: function (progress) { return 1 - Math.sin(Math.acos(progress)); }, back: function (progress) { var strength = 1.5; return (progress * progress) * ((strength + 1) * progress - strength); } }, /* Mirror easing Mirrors the provided easing function, used here for mirroring an easeIn into an easeInOut @param [number]: Progress, from 0 - 1, of current shift @param [function]: The easing function to mirror @returns [number]: The easing-adjusted delta */ mirrorEasing = function (progress, method) { return (progress <= 0.5) ? method(2 * progress) / 2 : (2 - method(2 * (1 - progress))) / 2; }, /* Reverse easing Reverses the output of the provided easing function, used for flipping easeIn curve to an easeOut. @param [number]: Progress, from 0 - 1, of current shift @param [function]: The easing function to reverse @returns [number]: The easing-adjusted delta */ reverseEasing = function (progress, method) { return 1 - method(1 - progress); }, /* Add new easing function Takes name and generates nameIn, nameOut, nameInOut, and easing functions to match @param [string]: Base name of the easing functions to generate @param [function]: Base easing function, as an easeIn, from which to generate Out and InOut */ generateVariations = function (name, method, isBaseIn) { var easeIn = name + EASE_IN, easeOut = name + EASE_OUT, easeInOut = name + EASE_IN_OUT, baseName = isBaseIn ? easeIn : easeOut, reverseName = isBaseIn ? easeOut : easeIn; // Create the In function easing[baseName] = method; // Create the Out function by reversing the transition curve easing[reverseName] = function (progress) { return reverseEasing(progress, easing[baseName]); }; // Create the InOut function by mirroring the transition curve easing[easeInOut] = function (progress) { return mirrorEasing(progress, easing[baseName]); }; }, easing = { /* Get the named easing function @param [string]: Name of the easing function to get @return [function || boolean]: Easing function or false if function undefined */ get: function (name) { var easing = this[name]; if (!easing) { throw name + INVALID_EASING; } return easing; }, /* Add Bezier Curve easing @param [string]: Name of new easing @parma [number]: X of coordinate 1 @parma [number]: Y of coordinate 1 @parma [number]: X of coordinate 2 @parma [number]: Y of coordinate 2 */ add: function (name, x1, y1, x2, y2) { if (!this[name]) { this[name] = new Bezier(x1, y1, x2, y2); } }, /* Ease value within ranged parameters @param [number]: Progress between 0 and 1 @param [number]: Value of 0 progress @param [number]: Value of 1 progress @param [string]: Easing to use @param [number]: Amplify progress out of specified range @return [number]: Value of eased progress in range */ withinRange: function (progress, from, to, ease, escapeAmp) { var progressLimited = calc.restricted(progress, 0, 1); if (progressLimited !== progress && escapeAmp) { ease = 'linear'; progressLimited = progressLimited + ((progress - progressLimited) * escapeAmp); } return calc.valueEased(progressLimited, from, to, this.get(ease)); }, /* Linear easing adjustment The default easing method, not added with .extend as it has no Out or InOut variation. @param [number]: Progress, from 0-1 @return [number]: Unadjusted progress */ linear: function (progress) { return progress; } }; // Initialise Easing (function () { var i = 0, key = ''; // Generate power easing functions for (; i < 4; i++) { baseEasing[powerEasing[i]] = generatePowerEasing(i + 2); } // Generate in/out/inOut easing variations for (key in baseEasing) { if (baseEasing.hasOwnProperty(key)) { generateVariations(key, baseEasing[key], true); } } })(); module.exports = easing;