From: Simon Brunel Date: Sat, 8 Jul 2017 07:44:00 +0000 (+0200) Subject: Move easing effects in separate file + unit tests X-Git-Tag: v2.7.0~1^2~60 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=56050dc9b7a17130efdbdcd3b8de46b728f25b84;p=thirdparty%2FChart.js.git Move easing effects in separate file + unit tests --- diff --git a/src/chart.js b/src/chart.js index 22aa7d893..8026cc856 100644 --- a/src/chart.js +++ b/src/chart.js @@ -4,6 +4,7 @@ var Chart = require('./core/core')(); require('./helpers/helpers.core')(Chart); +require('./helpers/helpers.easing')(Chart); require('./core/core.helpers')(Chart); require('./helpers/helpers.time')(Chart); require('./helpers/helpers.canvas')(Chart); diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 7f8050ad9..c367c36ae 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -484,7 +484,7 @@ module.exports = function(Chart) { easing: config.easing || animationOptions.easing, render: function(chart, animationObject) { - var easingFunction = helpers.easingEffects[animationObject.easing]; + var easingFunction = helpers.easing.effects[animationObject.easing]; var currentStep = animationObject.currentStep; var stepDecimal = currentStep / animationObject.numSteps; diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index e66d339d3..854a55575 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -388,203 +388,6 @@ module.exports = function(Chart) { return niceFraction * Math.pow(10, exponent); }; - // Easing functions adapted from Robert Penner's easing equations - // http://www.robertpenner.com/easing/ - var easingEffects = helpers.easingEffects = { - linear: function(t) { - return t; - }, - easeInQuad: function(t) { - return t * t; - }, - easeOutQuad: function(t) { - return -1 * t * (t - 2); - }, - easeInOutQuad: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t; - } - return -1 / 2 * ((--t) * (t - 2) - 1); - }, - easeInCubic: function(t) { - return t * t * t; - }, - easeOutCubic: function(t) { - return 1 * ((t = t / 1 - 1) * t * t + 1); - }, - easeInOutCubic: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t * t; - } - return 1 / 2 * ((t -= 2) * t * t + 2); - }, - easeInQuart: function(t) { - return t * t * t * t; - }, - easeOutQuart: function(t) { - return -1 * ((t = t / 1 - 1) * t * t * t - 1); - }, - easeInOutQuart: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t * t * t; - } - return -1 / 2 * ((t -= 2) * t * t * t - 2); - }, - easeInQuint: function(t) { - return 1 * (t /= 1) * t * t * t * t; - }, - easeOutQuint: function(t) { - return 1 * ((t = t / 1 - 1) * t * t * t * t + 1); - }, - easeInOutQuint: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t * t * t * t; - } - return 1 / 2 * ((t -= 2) * t * t * t * t + 2); - }, - easeInSine: function(t) { - return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1; - }, - easeOutSine: function(t) { - return 1 * Math.sin(t / 1 * (Math.PI / 2)); - }, - easeInOutSine: function(t) { - return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1); - }, - easeInExpo: function(t) { - return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1)); - }, - easeOutExpo: function(t) { - return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1); - }, - easeInOutExpo: function(t) { - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if ((t /= 1 / 2) < 1) { - return 1 / 2 * Math.pow(2, 10 * (t - 1)); - } - return 1 / 2 * (-Math.pow(2, -10 * --t) + 2); - }, - easeInCirc: function(t) { - if (t >= 1) { - return t; - } - return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1); - }, - easeOutCirc: function(t) { - return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t); - }, - easeInOutCirc: function(t) { - if ((t /= 1 / 2) < 1) { - return -1 / 2 * (Math.sqrt(1 - t * t) - 1); - } - return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1); - }, - easeInElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 1) === 1) { - return 1; - } - if (!p) { - p = 1 * 0.3; - } - if (a < Math.abs(1)) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); - }, - easeOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 1) === 1) { - return 1; - } - if (!p) { - p = 1 * 0.3; - } - if (a < Math.abs(1)) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1; - }, - easeInOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 1 / 2) === 2) { - return 1; - } - if (!p) { - p = 1 * (0.3 * 1.5); - } - if (a < Math.abs(1)) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - if (t < 1) { - return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); - } - return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1; - }, - easeInBack: function(t) { - var s = 1.70158; - return 1 * (t /= 1) * t * ((s + 1) * t - s); - }, - easeOutBack: function(t) { - var s = 1.70158; - return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1); - }, - easeInOutBack: function(t) { - var s = 1.70158; - if ((t /= 1 / 2) < 1) { - return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)); - } - return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - }, - easeInBounce: function(t) { - return 1 - easingEffects.easeOutBounce(1 - t); - }, - easeOutBounce: function(t) { - if ((t /= 1) < (1 / 2.75)) { - return 1 * (7.5625 * t * t); - } else if (t < (2 / 2.75)) { - return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); - } else if (t < (2.5 / 2.75)) { - return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); - } - return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); - }, - easeInOutBounce: function(t) { - if (t < 1 / 2) { - return easingEffects.easeInBounce(t * 2) * 0.5; - } - return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5; - } - }; // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ helpers.requestAnimFrame = (function() { if (typeof window === 'undefined') { diff --git a/src/helpers/helpers.easing.js b/src/helpers/helpers.easing.js new file mode 100644 index 000000000..975cc9288 --- /dev/null +++ b/src/helpers/helpers.easing.js @@ -0,0 +1,252 @@ +'use strict'; + +/** + * Easing functions adapted from Robert Penner's easing equations. + * http://www.robertpenner.com/easing/ + */ +var effects = { + linear: function(t) { + return t; + }, + + easeInQuad: function(t) { + return t * t; + }, + + easeOutQuad: function(t) { + return -t * (t - 2); + }, + + easeInOutQuad: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t; + } + return -0.5 * ((--t) * (t - 2) - 1); + }, + + easeInCubic: function(t) { + return t * t * t; + }, + + easeOutCubic: function(t) { + return (t = t - 1) * t * t + 1; + }, + + easeInOutCubic: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t; + } + return 0.5 * ((t -= 2) * t * t + 2); + }, + + easeInQuart: function(t) { + return t * t * t * t; + }, + + easeOutQuart: function(t) { + return -((t = t - 1) * t * t * t - 1); + }, + + easeInOutQuart: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t * t; + } + return -0.5 * ((t -= 2) * t * t * t - 2); + }, + + easeInQuint: function(t) { + return t * t * t * t * t; + }, + + easeOutQuint: function(t) { + return (t = t - 1) * t * t * t * t + 1; + }, + + easeInOutQuint: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t * t * t; + } + return 0.5 * ((t -= 2) * t * t * t * t + 2); + }, + + easeInSine: function(t) { + return -Math.cos(t * (Math.PI / 2)) + 1; + }, + + easeOutSine: function(t) { + return Math.sin(t * (Math.PI / 2)); + }, + + easeInOutSine: function(t) { + return -0.5 * (Math.cos(Math.PI * t) - 1); + }, + + easeInExpo: function(t) { + return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); + }, + + easeOutExpo: function(t) { + return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; + }, + + easeInOutExpo: function(t) { + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if ((t /= 0.5) < 1) { + return 0.5 * Math.pow(2, 10 * (t - 1)); + } + return 0.5 * (-Math.pow(2, -10 * --t) + 2); + }, + + easeInCirc: function(t) { + if (t >= 1) { + return t; + } + return -(Math.sqrt(1 - t * t) - 1); + }, + + easeOutCirc: function(t) { + return Math.sqrt(1 - (t = t - 1) * t); + }, + + easeInOutCirc: function(t) { + if ((t /= 0.5) < 1) { + return -0.5 * (Math.sqrt(1 - t * t) - 1); + } + return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); + }, + + easeInElastic: function(t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if (!p) { + p = 1 * 0.3; + } + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); + }, + + easeOutElastic: function(t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if (!p) { + p = 1 * 0.3; + } + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1; + }, + + easeInOutElastic: function(t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) { + return 0; + } + if ((t /= 0.5) === 2) { + return 1; + } + if (!p) { + p = 0.3 * 1.5; + } + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + if (t < 1) { + return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); + } + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + easeInBack: function(t) { + var s = 1.70158; + return t * t * ((s + 1) * t - s); + }, + + easeOutBack: function(t) { + var s = 1.70158; + return (t = t - 1) * t * ((s + 1) * t + s) + 1; + }, + + easeInOutBack: function(t) { + var s = 1.70158; + if ((t /= 0.5) < 1) { + return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); + } + return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + }, + + easeInBounce: function(t) { + return 1 - effects.easeOutBounce(1 - t); + }, + + easeOutBounce: function(t) { + if (t < (1 / 2.75)) { + return 7.5625 * t * t; + } + if (t < (2 / 2.75)) { + return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; + } + if (t < (2.5 / 2.75)) { + return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; + } + return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; + }, + + easeInOutBounce: function(t) { + if (t < 0.5) { + return effects.easeInBounce(t * 2) * 0.5; + } + return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; + } +}; + +module.exports = function(Chart) { + /** + * @namespace Chart.helpers.easing.effects + */ + Chart.helpers.easing = { + effects: effects + }; + + /** + * Provided for backward compatibility, use Chart.helpers.easing.effects instead. + * @function Chart.helpers.easingEffects + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + Chart.helpers.easingEffects = effects; + + return Chart.helpers.easing; +}; diff --git a/test/specs/global.deprecations.tests.js b/test/specs/global.deprecations.tests.js index 0f9feb894..8c9608694 100644 --- a/test/specs/global.deprecations.tests.js +++ b/test/specs/global.deprecations.tests.js @@ -84,6 +84,13 @@ describe('Deprecations', function() { }); }); + describe('Chart.helpers.easingEffects', function() { + it('should be defined and an alias of Chart.helpers.easing.effects', function() { + expect(Chart.helpers.easingEffects).toBeDefined(); + expect(Chart.helpers.easingEffects).toBe(Chart.helpers.easing.effects); + }); + }); + describe('Chart.helpers.drawRoundedRectangle', function() { it('should be defined and a function', function() { expect(Chart.helpers.drawRoundedRectangle).toBeDefined(); diff --git a/test/specs/helpers.easing.tests.js b/test/specs/helpers.easing.tests.js new file mode 100644 index 000000000..b27655c9b --- /dev/null +++ b/test/specs/helpers.easing.tests.js @@ -0,0 +1,61 @@ +'use strict'; + +describe('Chart.helpers.easing', function() { + var easing = Chart.helpers.easing; + + describe('effects', function() { + var expected = { + easeInOutBack: [-0, -0.03751855, -0.09255566, -0.07883348, 0.08992579, 0.5, 0.91007421, 1.07883348, 1.09255566, 1.03751855, 1], + easeInOutBounce: [0, 0.03, 0.11375, 0.045, 0.34875, 0.5, 0.65125, 0.955, 0.88625, 0.97, 1], + easeInOutCirc: [-0, 0.01010205, 0.04174243, 0.1, 0.2, 0.5, 0.8, 0.9, 0.95825757, 0.98989795, 1], + easeInOutCubic: [0, 0.004, 0.032, 0.108, 0.256, 0.5, 0.744, 0.892, 0.968, 0.996, 1], + easeInOutElastic: [0, 0.00033916, -0.00390625, 0.02393889, -0.11746158, 0.5, 1.11746158, 0.97606111, 1.00390625, 0.99966084, 1], + easeInOutExpo: [0, 0.00195313, 0.0078125, 0.03125, 0.125, 0.5, 0.875, 0.96875, 0.9921875, 0.99804688, 1], + easeInOutQuad: [0, 0.02, 0.08, 0.18, 0.32, 0.5, 0.68, 0.82, 0.92, 0.98, 1], + easeInOutQuart: [0, 0.0008, 0.0128, 0.0648, 0.2048, 0.5, 0.7952, 0.9352, 0.9872, 0.9992, 1], + easeInOutQuint: [0, 0.00016, 0.00512, 0.03888, 0.16384, 0.5, 0.83616, 0.96112, 0.99488, 0.99984, 1], + easeInOutSine: [-0, 0.02447174, 0.0954915, 0.20610737, 0.3454915, 0.5, 0.6545085, 0.79389263, 0.9045085, 0.97552826, 1], + easeInBack: [-0, -0.01431422, -0.04645056, -0.08019954, -0.09935168, -0.0876975, -0.02902752, 0.09286774, 0.29419776, 0.59117202, 1], + easeInBounce: [0, 0.011875, 0.06, 0.069375, 0.2275, 0.234375, 0.09, 0.319375, 0.6975, 0.924375, 1], + easeInCirc: [-0, 0.00501256, 0.0202041, 0.0460608, 0.08348486, 0.1339746, 0.2, 0.28585716, 0.4, 0.56411011, 1], + easeInCubic: [0, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.512, 0.729, 1], + easeInExpo: [0, 0.00195313, 0.00390625, 0.0078125, 0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1], + easeInElastic: [0, 0.00195313, -0.00195313, -0.00390625, 0.015625, -0.015625, -0.03125, 0.125, -0.125, -0.25, 1], + easeInQuad: [0, 0.01, 0.04, 0.09, 0.16, 0.25, 0.36, 0.49, 0.64, 0.81, 1], + easeInQuart: [0, 0.0001, 0.0016, 0.0081, 0.0256, 0.0625, 0.1296, 0.2401, 0.4096, 0.6561, 1], + easeInQuint: [0, 0.00001, 0.00032, 0.00243, 0.01024, 0.03125, 0.07776, 0.16807, 0.32768, 0.59049, 1], + easeInSine: [0, 0.01231166, 0.04894348, 0.10899348, 0.19098301, 0.29289322, 0.41221475, 0.5460095, 0.69098301, 0.84356553, 1], + easeOutBack: [0, 0.40882798, 0.70580224, 0.90713226, 1.02902752, 1.0876975, 1.09935168, 1.08019954, 1.04645056, 1.01431422, 1], + easeOutBounce: [0, 0.075625, 0.3025, 0.680625, 0.91, 0.765625, 0.7725, 0.930625, 0.94, 0.988125, 1], + easeOutCirc: [0, 0.43588989, 0.6, 0.71414284, 0.8, 0.8660254, 0.91651514, 0.9539392, 0.9797959, 0.99498744, 1], + easeOutElastic: [0, 1.25, 1.125, 0.875, 1.03125, 1.015625, 0.984375, 1.00390625, 1.00195313, 0.99804688, 1], + easeOutExpo: [0, 0.5, 0.75, 0.875, 0.9375, 0.96875, 0.984375, 0.9921875, 0.99609375, 0.99804688, 1], + easeOutCubic: [0, 0.271, 0.488, 0.657, 0.784, 0.875, 0.936, 0.973, 0.992, 0.999, 1], + easeOutQuad: [0, 0.19, 0.36, 0.51, 0.64, 0.75, 0.84, 0.91, 0.96, 0.99, 1], + easeOutQuart: [-0, 0.3439, 0.5904, 0.7599, 0.8704, 0.9375, 0.9744, 0.9919, 0.9984, 0.9999, 1], + easeOutQuint: [0, 0.40951, 0.67232, 0.83193, 0.92224, 0.96875, 0.98976, 0.99757, 0.99968, 0.99999, 1], + easeOutSine: [0, 0.15643447, 0.30901699, 0.4539905, 0.58778525, 0.70710678, 0.80901699, 0.89100652, 0.95105652, 0.98768834, 1], + linear: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] + }; + + function generate(method) { + var fn = easing.effects[method]; + var accuracy = Math.pow(10, 8); + var count = 10; + var values = []; + var i; + + for (i=0; i<=count; ++i) { + values.push(Math.round(accuracy * fn(i/count)) / accuracy); + } + + return values; + } + + Object.keys(easing.effects).forEach(function(method) { + it ('"' + method + '" should return expected values', function() { + expect(generate(method)).toEqual(expected[method]); + }); + }); + }); +});