diff --git a/README.md b/README.md index 48127e9..c078e44 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,13 @@ A minimal native Javascript tweening engine with jQuery plugin, fo # CDN Thanks to jsdelivr, we have CDN link here. +# NPM/Bower +You can install this through NPM or bower respectively: + + $ npm install kute.js + # or + $ bower install kute.js + # Basic Usage At a glance, you can write one line and you're done. ```javascript @@ -16,6 +23,23 @@ new KUTE.fromTo('selector', fromValues, toValues, options); $('selector').KUTE('fromTo', fromValues, toValues, options); ``` +# CommonJS/AMD support +You can use this module through any of the common javascript module systems. For instance: + +```javascript +// NodeJS/CommonJS style +var kute = require("kute.js"); +// Add Bezier/Easing... +require("kute.js/kute-bezier"); + +// AMD +define([ + "kute.js", + "kute.js/kute-bezier.js" +], function(KUTE){ + // ... +}); +``` # Advanced Usage Quite easily, you can write 'bit more lines and you're making the earth go round. @@ -26,9 +50,9 @@ KUTE.fromTo(el, { { translate: 0, opacity: 1 }, // fromValues { translate: 150, opacity: 0 }, // toValues { duration: 500, delay: 0, easing : 'exponentialInOut', // basic options - + //callbacks - start: functionOne, // run function when tween starts + start: functionOne, // run function when tween starts complete: functionTwo, // run function when tween animation is finished update: functionThree // run function while tween running stop: functionThree // run function when tween stopped @@ -39,7 +63,7 @@ KUTE.fromTo(el, { ); ``` -# Demo +# Demo For documentation, examples and other cool tips, check the demo. #jQuery Plugin @@ -51,7 +75,7 @@ That's right, there you have it, just a few bits of code to bridge the awesome ` * computes properties' values properly according to their measurement unit (px,%,deg,etc) * properly handles cross browser 3D `transform` with `perspective` and `perspective-origin` for element or it's parent * converts `HEX` colors to `RGB` and tweens the numeric values, then ALWAYS updates color via `RGB` -* properly replaces `top`, `centered` or any other background position with proper value to be able to tween +* properly replaces `top`, `centered` or any other background position with proper value to be able to tween * for most supported properties it reads the current element computed style property value as initial value (via `currentStyle || getComputedStyle`) * because it can read properties values from previous tween animations, KUTE.js can do some awesome chaining with it's `.to()` method * allows you to add many callbacks: `start`, `update`, `complete`, `pause`, `stop`, and they can be set as tween options diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..2b6bdd6 --- /dev/null +++ b/bower.json @@ -0,0 +1,30 @@ +{ + "name": "KUTE.js", + "version": "0.9.4", + "homepage": "http://thednp.github.io/kute.js", + "authors": [ + "thednp" + ], + "description": "A minimal Native Javascript animation engine with jQuery plugin.", + "main": "kute.js", + "moduleType": [ + "amd", + "globals", + "node" + ], + "keywords": [ + "animations", + "native-javascript", + "kute.js", + "tweening", + "engine" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/kute-bezier.js b/kute-bezier.js index 44c23b9..64faa5b 100644 --- a/kute-bezier.js +++ b/kute-bezier.js @@ -6,154 +6,173 @@ * Licensed under MIT-License */ -KUTE.Ease = {}; - -KUTE.Ease.bezier = function(mX1, mY1, mX2, mY2) { - return _bz.pB(mX1, mY1, mX2, mY2); -}; - -var _bz = KUTE.Ease.bezier.prototype; - -// These values are established by empiricism with tests (tradeoff: performance VS precision) -_bz.ni = 4; // NEWTON_ITERATIONS -_bz.nms = 0.001; // NEWTON_MIN_SLOPE -_bz.sp = 0.0000001; // SUBDIVISION_PRECISION -_bz.smi = 10, // SUBDIVISION_MAX_ITERATIONS - -_bz.ksts = 11; // k Spline Table Size -_bz.ksss = 1.0 / (_bz.ksts - 1.0); // k Sample Step Size - -_bz.f32as = 'Float32Array' in window; // float32ArraySupported -_bz.msv = _bz.f32as ? new Float32Array (_bz.ksts) : new Array (_bz.ksts); // m Sample Values - -_bz.A = function(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }; -_bz.B = function(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }; -_bz.C = function(aA1) { return 3.0 * aA1; }; - -_bz.r = {}; -_bz.pB = function (mX1, mY1, mX2, mY2) { -this._p = false; var self = this; - -_bz.r = function(aX){ - if (!self._p) _bz.pc(mX1, mX2, mY1, mY2); - if (mX1 === mY1 && mX2 === mY2) return aX; - - if (aX === 0) return 0; - if (aX === 1) return 1; - return _bz.cB(_bz.gx(aX, mX1, mX2), mY1, mY2); -}; -return _bz.r; -}; - -// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. -_bz.cB = function(aT, aA1, aA2) { // calc Bezier - return ((_bz.A(aA1, aA2)*aT + _bz.B(aA1, aA2))*aT + _bz.C(aA1))*aT; -}; - -// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. -_bz.gS = function (aT, aA1, aA2) { // getSlope - return 3.0 * _bz.A(aA1, aA2)*aT*aT + 2.0 * _bz.B(aA1, aA2) * aT + _bz.C(aA1); -}; - -_bz.bS = function(a, aA, aB, mX1, mX2) { // binary Subdivide - var x, t, i = 0, j = _bz.sp, y = _bz.smi; - do { - t = aA + (aB - aA) / 2.0; - x = _bz.cB(t, mX1, mX2) - a; - if (x > 0.0) { - aB = t; - } else { - aA = t; - } - } while (Math.abs(x) > j && ++i < y); - return t; -}; - -_bz.nri = function (aX, agt, mX1, mX2) { // newton Raphs on Iterate -var i = 0, j = _bz.ni; - for (i; i < j; ++i) { - var cs = _bz.gS(agt, mX1, mX2); - if (cs === 0.0) return agt; - var x = _bz.cB(agt, mX1, mX2) - aX; - agt -= x / cs; - } - return agt; -}; - -_bz.csv = function (mX1, mX2) { // calc Sample Values -var i = 0, j = _bz.ksts; - for (i; i < j; ++i) { - _bz.msv[i] = _bz.cB(i * _bz.ksss, mX1, mX2); - } -}; - -_bz.gx = function (aX,mX1,mX2) { //get to X - var iS = 0.0, cs = 1, ls = _bz.ksts - 1; - - for (; cs != ls && _bz.msv[cs] <= aX; ++cs) { - iS += _bz.ksss; - } - --cs; - - // Interpolate to provide an initial guess for t - var dist = (aX - _bz.msv[cs]) / (_bz.msv[cs+1] - _bz.msv[cs]), - gt = iS + dist * _bz.ksss, - ins = _bz.gS(gt, mX1, mX2), - fiS = iS + _bz.ksss; - - if (ins >= _bz.nms) { - return _bz.nri(aX, gt, mX1, mX2); - } else if (ins === 0.0) { - return gt; +(function(kute_ea){ + // Obtain a reference to the base KUTE. + // Since KUTE supports a variety of module systems, + // we need to pick up which one to use. + if(define == "function") { + define(["./kute.js"], function(KUTE){ kute_ea(KUTE); return KUTE; }); + } else if(typeof module == "object" && typeof require == "function") { + // We assume, that require() is sync. + var KUTE = require("./kute.js"); + kute_ea(KUTE); + // Export the modified one. Not really required, but convenient. + module.exports = KUTE; + } else if(typeof root.KUTE != "undefined") { + kute_ea(root.KUTE); } else { - return _bz.bS(aX, iS, fiS, mX1, mX2); + throw new Error("KUTE.js Bezier/Easing depends on KUTE.js. Read the docs for more info.") } -}; +})(function(KUTE){ + KUTE.Ease = {}; -_bz.pc = function(mX1, mX2, mY1, mY2) { - this._p = true; -if (mX1 != mY1 || mX2 != mY2) - _bz.csv(mX1, mX2); -}; - -// predefined bezier based easings, can be accessed via string, eg 'easeIn' or 'easeInOutQuart' -// _easings = ["linear","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInExpo","easeOutExpo","easeInOutExpo","slowMo","slowMo1","slowMo2"], -KUTE.Ease.easeIn = function(){ return _bz.pB(0.42, 0.0, 1.00, 1.0); }; -KUTE.Ease.easeOut = function(){ return _bz.pB(0.00, 0.0, 0.58, 1.0); }; -KUTE.Ease.easeInOut = function(){ return _bz.pB(0.50, 0.16, 0.49, 0.86); }; - -KUTE.Ease.easeInSine = function(){ return _bz.pB(0.47, 0, 0.745, 0.715); }; -KUTE.Ease.easeOutSine = function(){ return _bz.pB(0.39, 0.575, 0.565, 1); }; -KUTE.Ease.easeInOutSine = function(){ return _bz.pB(0.445, 0.05, 0.55, 0.95); }; + KUTE.Ease.bezier = function(mX1, mY1, mX2, mY2) { + return _bz.pB(mX1, mY1, mX2, mY2); + }; -KUTE.Ease.easeInQuad = function () { return _bz.pB(0.550, 0.085, 0.680, 0.530); }; -KUTE.Ease.easeOutQuad = function () { return _bz.pB(0.250, 0.460, 0.450, 0.940); }; -KUTE.Ease.easeInOutQuad = function () { return _bz.pB(0.455, 0.030, 0.515, 0.955); }; + var _bz = KUTE.Ease.bezier.prototype; -KUTE.Ease.easeInCubic = function () { return _bz.pB(0.55, 0.055, 0.675, 0.19); }; -KUTE.Ease.easeOutCubic = function () { return _bz.pB(0.215, 0.61, 0.355, 1); }; -KUTE.Ease.easeInOutCubic = function () { return _bz.pB(0.645, 0.045, 0.355, 1); }; + // These values are established by empiricism with tests (tradeoff: performance VS precision) + _bz.ni = 4; // NEWTON_ITERATIONS + _bz.nms = 0.001; // NEWTON_MIN_SLOPE + _bz.sp = 0.0000001; // SUBDIVISION_PRECISION + _bz.smi = 10, // SUBDIVISION_MAX_ITERATIONS -KUTE.Ease.easeInQuart = function () { return _bz.pB(0.895, 0.03, 0.685, 0.22); }; -KUTE.Ease.easeOutQuart = function () { return _bz.pB(0.165, 0.84, 0.44, 1); }; -KUTE.Ease.easeInOutQuart = function () { return _bz.pB(0.77, 0, 0.175, 1); }; + _bz.ksts = 11; // k Spline Table Size + _bz.ksss = 1.0 / (_bz.ksts - 1.0); // k Sample Step Size -KUTE.Ease.easeInQuint = function(){ return _bz.pB(0.755, 0.05, 0.855, 0.06); }; -KUTE.Ease.easeOutQuint = function(){ return _bz.pB(0.23, 1, 0.32, 1); }; -KUTE.Ease.easeInOutQuint = function(){ return _bz.pB(0.86, 0, 0.07, 1); }; - -KUTE.Ease.easeInExpo = function(){ return _bz.pB(0.95, 0.05, 0.795, 0.035); }; -KUTE.Ease.easeOutExpo = function(){ return _bz.pB(0.19, 1, 0.22, 1); }; -KUTE.Ease.easeInOutExpo = function(){ return _bz.pB(1, 0, 0, 1); }; + _bz.f32as = 'Float32Array' in window; // float32ArraySupported + _bz.msv = _bz.f32as ? new Float32Array (_bz.ksts) : new Array (_bz.ksts); // m Sample Values -KUTE.Ease.easeInCirc = function(){ return _bz.pB(0.6, 0.04, 0.98, 0.335); }; -KUTE.Ease.easeOutCirc = function(){ return _bz.pB(0.075, 0.82, 0.165, 1); }; -KUTE.Ease.easeInOutCirc = function(){ return _bz.pB(0.785, 0.135, 0.15, 0.86); }; + _bz.A = function(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }; + _bz.B = function(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }; + _bz.C = function(aA1) { return 3.0 * aA1; }; -KUTE.Ease.easeInBack = function(){ return _bz.pB(0.600, -0.280, 0.735, 0.045); }; -KUTE.Ease.easeOutBack = function(){ return _bz.pB(0.175, 0.885, 0.320, 1.275); }; -KUTE.Ease.easeInOutBack = function(){ return _bz.pB(0.68, -0.55, 0.265, 1.55); }; + _bz.r = {}; + _bz.pB = function (mX1, mY1, mX2, mY2) { + this._p = false; var self = this; -KUTE.Ease.slowMo = function(){ return _bz.pB(0.000, 0.500, 1.000, 0.500); }; -KUTE.Ease.slowMo1 = function(){ return _bz.pB(0.000, 0.700, 1.000, 0.300); }; -KUTE.Ease.slowMo2 = function(){ return _bz.pB(0.000, 0.900, 1.000, 0.100); }; \ No newline at end of file + _bz.r = function(aX){ + if (!self._p) _bz.pc(mX1, mX2, mY1, mY2); + if (mX1 === mY1 && mX2 === mY2) return aX; + + if (aX === 0) return 0; + if (aX === 1) return 1; + return _bz.cB(_bz.gx(aX, mX1, mX2), mY1, mY2); + }; + return _bz.r; + }; + + // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. + _bz.cB = function(aT, aA1, aA2) { // calc Bezier + return ((_bz.A(aA1, aA2)*aT + _bz.B(aA1, aA2))*aT + _bz.C(aA1))*aT; + }; + + // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. + _bz.gS = function (aT, aA1, aA2) { // getSlope + return 3.0 * _bz.A(aA1, aA2)*aT*aT + 2.0 * _bz.B(aA1, aA2) * aT + _bz.C(aA1); + }; + + _bz.bS = function(a, aA, aB, mX1, mX2) { // binary Subdivide + var x, t, i = 0, j = _bz.sp, y = _bz.smi; + do { + t = aA + (aB - aA) / 2.0; + x = _bz.cB(t, mX1, mX2) - a; + if (x > 0.0) { + aB = t; + } else { + aA = t; + } + } while (Math.abs(x) > j && ++i < y); + return t; + }; + + _bz.nri = function (aX, agt, mX1, mX2) { // newton Raphs on Iterate + var i = 0, j = _bz.ni; + for (i; i < j; ++i) { + var cs = _bz.gS(agt, mX1, mX2); + if (cs === 0.0) return agt; + var x = _bz.cB(agt, mX1, mX2) - aX; + agt -= x / cs; + } + return agt; + }; + + _bz.csv = function (mX1, mX2) { // calc Sample Values + var i = 0, j = _bz.ksts; + for (i; i < j; ++i) { + _bz.msv[i] = _bz.cB(i * _bz.ksss, mX1, mX2); + } + }; + + _bz.gx = function (aX,mX1,mX2) { //get to X + var iS = 0.0, cs = 1, ls = _bz.ksts - 1; + + for (; cs != ls && _bz.msv[cs] <= aX; ++cs) { + iS += _bz.ksss; + } + --cs; + + // Interpolate to provide an initial guess for t + var dist = (aX - _bz.msv[cs]) / (_bz.msv[cs+1] - _bz.msv[cs]), + gt = iS + dist * _bz.ksss, + ins = _bz.gS(gt, mX1, mX2), + fiS = iS + _bz.ksss; + + if (ins >= _bz.nms) { + return _bz.nri(aX, gt, mX1, mX2); + } else if (ins === 0.0) { + return gt; + } else { + return _bz.bS(aX, iS, fiS, mX1, mX2); + } + }; + + _bz.pc = function(mX1, mX2, mY1, mY2) { + this._p = true; + if (mX1 != mY1 || mX2 != mY2) + _bz.csv(mX1, mX2); + }; + + // predefined bezier based easings, can be accessed via string, eg 'easeIn' or 'easeInOutQuart' + // _easings = ["linear","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInExpo","easeOutExpo","easeInOutExpo","slowMo","slowMo1","slowMo2"], + KUTE.Ease.easeIn = function(){ return _bz.pB(0.42, 0.0, 1.00, 1.0); }; + KUTE.Ease.easeOut = function(){ return _bz.pB(0.00, 0.0, 0.58, 1.0); }; + KUTE.Ease.easeInOut = function(){ return _bz.pB(0.50, 0.16, 0.49, 0.86); }; + + KUTE.Ease.easeInSine = function(){ return _bz.pB(0.47, 0, 0.745, 0.715); }; + KUTE.Ease.easeOutSine = function(){ return _bz.pB(0.39, 0.575, 0.565, 1); }; + KUTE.Ease.easeInOutSine = function(){ return _bz.pB(0.445, 0.05, 0.55, 0.95); }; + + KUTE.Ease.easeInQuad = function () { return _bz.pB(0.550, 0.085, 0.680, 0.530); }; + KUTE.Ease.easeOutQuad = function () { return _bz.pB(0.250, 0.460, 0.450, 0.940); }; + KUTE.Ease.easeInOutQuad = function () { return _bz.pB(0.455, 0.030, 0.515, 0.955); }; + + KUTE.Ease.easeInCubic = function () { return _bz.pB(0.55, 0.055, 0.675, 0.19); }; + KUTE.Ease.easeOutCubic = function () { return _bz.pB(0.215, 0.61, 0.355, 1); }; + KUTE.Ease.easeInOutCubic = function () { return _bz.pB(0.645, 0.045, 0.355, 1); }; + + KUTE.Ease.easeInQuart = function () { return _bz.pB(0.895, 0.03, 0.685, 0.22); }; + KUTE.Ease.easeOutQuart = function () { return _bz.pB(0.165, 0.84, 0.44, 1); }; + KUTE.Ease.easeInOutQuart = function () { return _bz.pB(0.77, 0, 0.175, 1); }; + + KUTE.Ease.easeInQuint = function(){ return _bz.pB(0.755, 0.05, 0.855, 0.06); }; + KUTE.Ease.easeOutQuint = function(){ return _bz.pB(0.23, 1, 0.32, 1); }; + KUTE.Ease.easeInOutQuint = function(){ return _bz.pB(0.86, 0, 0.07, 1); }; + + KUTE.Ease.easeInExpo = function(){ return _bz.pB(0.95, 0.05, 0.795, 0.035); }; + KUTE.Ease.easeOutExpo = function(){ return _bz.pB(0.19, 1, 0.22, 1); }; + KUTE.Ease.easeInOutExpo = function(){ return _bz.pB(1, 0, 0, 1); }; + + KUTE.Ease.easeInCirc = function(){ return _bz.pB(0.6, 0.04, 0.98, 0.335); }; + KUTE.Ease.easeOutCirc = function(){ return _bz.pB(0.075, 0.82, 0.165, 1); }; + KUTE.Ease.easeInOutCirc = function(){ return _bz.pB(0.785, 0.135, 0.15, 0.86); }; + + KUTE.Ease.easeInBack = function(){ return _bz.pB(0.600, -0.280, 0.735, 0.045); }; + KUTE.Ease.easeOutBack = function(){ return _bz.pB(0.175, 0.885, 0.320, 1.275); }; + KUTE.Ease.easeInOutBack = function(){ return _bz.pB(0.68, -0.55, 0.265, 1.55); }; + + KUTE.Ease.slowMo = function(){ return _bz.pB(0.000, 0.500, 1.000, 0.500); }; + KUTE.Ease.slowMo1 = function(){ return _bz.pB(0.000, 0.700, 1.000, 0.300); }; + KUTE.Ease.slowMo2 = function(){ return _bz.pB(0.000, 0.900, 1.000, 0.100); }; +}); diff --git a/kute-jquery.js b/kute-jquery.js index 153a26a..1526e0f 100644 --- a/kute-jquery.js +++ b/kute-jquery.js @@ -4,23 +4,44 @@ * Licensed under MIT-License */ -(function($) { - $.fn.KUTE = function( method, start, end, ops ) { // method can be Animate(), fromTo(), to(), stop(), start(), chain(), pause() + (function(kutejQuery){ + // We need to require the root KUTE and jQuery. + if(define == "function") { + define(["./kute.js", "jQuery"], function(KUTE, $){ + kutejQuery($, KUTE); + return KUTE; + }); + } else if(typeof module == "object" && typeof require == "function") { + // We assume, that require() is sync. + var KUTE = require("./kute.js"); + var $ = require("jQuery"); + kutejQuery($, KUTE); + // Export the modified one. Not really required, but convenient. + module.exports = $; + } else if(typeof root.KUTE != "undefined") { + // jQuery always has two ways of existing... Find one, and pass. + var $ = root.jQuery || root.$; + kutejQuery($, root.KUTE); + } else { + throw new Error("KUTE.js jQuery depends on KUTE.js and jQuery. Read the docs for more info.") + } + })(function($, KUTE) { + $.fn.KUTE = function( method, start, end, ops ) { // method can be Animate(), fromTo(), to(), stop(), start(), chain(), pause() var tws = [], i, l = this.length; - + for (i=0;i 0.001) { - _kpg.L = curve.b - curve.a; - curve = { - a: curve.b, - b: curve.b + _kpg.L * bounciness, - H: curve.H * bounciness * bounciness + frictionT = (t / (1 - aS)) - (aS / (1 - aS)); + if (t < aS) { + yS = (aS / (1 - aS)) - (aS / (1 - aS)); + y0 = (0 / (1 - aS)) - (aS / (1 - aS)); + b = Math.acos(1 / _kps.A1(t,yS)); + a = (Math.acos(1 / _kps.A1(t,y0)) - b) / (fq * (-aS)); + A = _kps.A1; + } else { + A = _kps.A2; + b = 0; + a = 1; + } + At = A(frictionT,aS,aSt,fc); + angle = fq * (t - aS) * a + b; + return 1 - (At * Math.cos(angle)); }; - } - return curve.b; - })(); - (function() { - var L2, b, curve, _results; - b = Math.sqrt(2 / (gravity * _kpg.L * _kpg.L)); - curve = { - a: -b, - b: b, - H: 1 + return _kps.run; }; - if (initialForce) { - curve.a = 0; - curve.b = curve.b * 2; - } - curves.push(curve); - L2 = _kpg.L; - _results = []; - while (curve.b < 1 && curve.H > 0.001) { - L2 = curve.b - curve.a; - curve = { - a: curve.b, - b: curve.b + L2 * bounciness, - H: curve.H * elasticity + + var _kps = _kp.spring.prototype; + _kps.run = {}; + _kps.A1 = function(t,aS,aSt) { + var a, b, x0, x1; + x0 = aS / (1 - aS); + x1 = 0; + b = (x0 - (0.8 * x1)) / (x0 - x1); + a = (0.8 - b) / x0; + return (a * t * aSt / 100) + b; + }; + _kps.A2 = function(t,aS,aSt,f) { + return Math.pow(f / 10, -t) * (1 - t); + }; + + + // bounce + _kp.bounce = function(options) { + options = options || {}; + var fq = Math.max(1, (options.frequency || 300) / 20), + f = Math.pow(20, (options.friction || 200) / 100); + + _kpo.run = function(t) { + var At = Math.pow(f / 10, -t) * (1 - t), + angle = fq * t * 1 + _hPI; + return At * Math.cos(angle); }; - _results.push(curves.push(curve)); - } - return _results; - })(); - _kpg.fn = function(t) { - var curve, i, v; - i = 0; - curve = curves[i]; - while (!(t >= curve.a && t <= curve.b)) { - i += 1; - curve = curves[i]; - if (!curve) { - break; + return _kpo.run; + }; + + var _kpo = _kp.bounce.prototype; + _kpo.run = {}; + + + // gravity + _kp.gravity = function(options) { + var bounciness, curves, elasticity, gravity, initialForce; + + options = options || {}; + bounciness = ( options.bounciness || 400 ) / 1250; + elasticity = ( options.elasticity || 200 ) / 1000; + initialForce = options.initialForce || false; + + gravity = 100; + curves = []; + _kpg.L = (function() { + var b, curve; + b = Math.sqrt(2 / gravity); + curve = { + a: -b, + b: b, + H: 1 + }; + if (initialForce) { + curve.a = 0; + curve.b = curve.b * 2; + } + while (curve.H > 0.001) { + _kpg.L = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + _kpg.L * bounciness, + H: curve.H * bounciness * bounciness + }; + } + return curve.b; + })(); + + (function() { + var L2, b, curve, _results; + b = Math.sqrt(2 / (gravity * _kpg.L * _kpg.L)); + curve = { + a: -b, + b: b, + H: 1 + }; + if (initialForce) { + curve.a = 0; + curve.b = curve.b * 2; + } + curves.push(curve); + L2 = _kpg.L; + _results = []; + while (curve.b < 1 && curve.H > 0.001) { + L2 = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + L2 * bounciness, + H: curve.H * elasticity + }; + _results.push(curves.push(curve)); + } + return _results; + })(); + _kpg.fn = function(t) { + var curve, i, v; + i = 0; + curve = curves[i]; + while (!(t >= curve.a && t <= curve.b)) { + i += 1; + curve = curves[i]; + if (!curve) { + break; + } + } + if (!curve) { + v = initialForce ? 0 : 1; + } else { + v = _kpg.getPointInCurve(curve.a, curve.b, curve.H, t, options, _kpg.L); + } + return v; + }; + + return _kpg.fn; + }; + + var _kpg = _kp.gravity.prototype; + _kpg.L = {}; + _kpg.fn = {}; + _kpg.getPointInCurve = function(a, b, H, t, o, L) { + var c, t2; + L = b - a; + t2 = (2 / L) * t - 1 - (a * 2 / L); + c = t2 * t2 * H - H + 1; + if (o.initialForce) { + c = 1 - c; } - } - if (!curve) { - v = initialForce ? 0 : 1; - } else { - v = _kpg.getPointInCurve(curve.a, curve.b, curve.H, t, options, _kpg.L); - } - return v; - }; + return c; + }; - return _kpg.fn; -}; - -var _kpg = _kp.gravity.prototype; -_kpg.L = {}; -_kpg.fn = {}; -_kpg.getPointInCurve = function(a, b, H, t, o, L) { - var c, t2; - L = b - a; - t2 = (2 / L) * t - 1 - (a * 2 / L); - c = t2 * t2 * H - H + 1; - if (o.initialForce) { - c = 1 - c; - } - return c; -}; - -//throw up and pull down by gravity -_kp.forceWithGravity = function(o) { - var ops = o || {}; - ops.initialForce = true; - return _kp.gravity(ops); -}; + //throw up and pull down by gravity + _kp.forceWithGravity = function(o) { + var ops = o || {}; + ops.initialForce = true; + return _kp.gravity(ops); + }; -// multi point bezier -_kp.bezier = function(options) { - options = options || {}; - var points = options.points, - returnsToSelf = false, Bs = []; + // multi point bezier + _kp.bezier = function(options) { + options = options || {}; + var points = options.points, + returnsToSelf = false, Bs = []; - (function() { - var i, k; + (function() { + var i, k; - for (i in points) { - k = parseInt(i); - if (k >= points.length - 1) { + for (i in points) { + k = parseInt(i); + if (k >= points.length - 1) { + break; + } + _kpb.fn(points[k], points[k + 1], Bs); + } + return Bs; + })(); + + _kpb.run = function(t) { + if (t === 0) { + return 0; + } else if (t === 1) { + return 1; + } else { + return _kpb.yForX(t, Bs, returnsToSelf); + } + }; + return _kpb.run; + }; + + var _kpb = _kp.bezier.prototype; + _kpb.B2 = {}; + _kpb.run = {}; + + _kpb.fn = function(pointA, pointB, Bs) { + var B2 = function(t) { + return _kpb.Bezier(t, pointA, pointA.cp[pointA.cp.length - 1], pointB.cp[0], pointB); + }; + return Bs.push(B2); + }; + + _kpb.Bezier = function(t, p0, p1, p2, p3) { + return { + x: (Math.pow(1 - t, 3) * p0.x) + (3 * Math.pow(1 - t, 2) * t * p1.x) + (3 * (1 - t) * Math.pow(t, 2) * p2.x) + Math.pow(t, 3) * p3.x, + y: (Math.pow(1 - t, 3) * p0.y) + (3 * Math.pow(1 - t, 2) * t * p1.y) + (3 * (1 - t) * Math.pow(t, 2) * p2.y) + Math.pow(t, 3) * p3.y + }; + }; + + _kpb.yForX = function(xTarget, Bs, rTS) { + var B, aB, i, lower, percent, upper, x, xT, _i = 0, _len = Bs.length; + B = null; + for (_i; _i < _len; _i++) { + aB = Bs[_i]; + if (xTarget >= aB(0).x && xTarget <= aB(1).x) { + B = aB; + } + if (B !== null) { break; } - _kpb.fn(points[k], points[k + 1], Bs); } - return Bs; - })(); - - _kpb.run = function(t) { - if (t === 0) { - return 0; - } else if (t === 1) { - return 1; - } else { - return _kpb.yForX(t, Bs, returnsToSelf); + if (!B) { + return ( rTS ? 0 : 1 ); } + xT = 0.0001; // xTolerance + lower = 0; upper = 1; + percent = (upper + lower) / 2; + x = B(percent).x; i = 0; + while (Math.abs(xTarget - x) > xT && i < 100) { + if (xTarget > x) { + lower = percent; + } else { + upper = percent; + } + percent = (upper + lower) / 2; + x = B(percent).x; + i++; + } + return B(percent).y; }; - return _kpb.run; -}; -var _kpb = _kp.bezier.prototype; -_kpb.B2 = {}; -_kpb.run = {}; + _kp.physicsInOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] } ] }); + }; -_kpb.fn = function(pointA, pointB, Bs) { - var B2 = function(t) { - return _kpb.Bezier(t, pointA, pointA.cp[pointA.cp.length - 1], pointB.cp[0], pointB); - }; - return Bs.push(B2); -}; + _kp.physicsIn = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 1, y: 1 } ] } ] }); + }; -_kpb.Bezier = function(t, p0, p1, p2, p3) { - return { - x: (Math.pow(1 - t, 3) * p0.x) + (3 * Math.pow(1 - t, 2) * t * p1.x) + (3 * (1 - t) * Math.pow(t, 2) * p2.x) + Math.pow(t, 3) * p3.x, - y: (Math.pow(1 - t, 3) * p0.y) + (3 * Math.pow(1 - t, 2) * t * p1.y) + (3 * (1 - t) * Math.pow(t, 2) * p2.y) + Math.pow(t, 3) * p3.y - }; -}; + _kp.physicsOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0, y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] }] }); + }; -_kpb.yForX = function(xTarget, Bs, rTS) { - var B, aB, i, lower, percent, upper, x, xT, _i = 0, _len = Bs.length; - B = null; - for (_i; _i < _len; _i++) { - aB = Bs[_i]; - if (xTarget >= aB(0).x && xTarget <= aB(1).x) { - B = aB; - } - if (B !== null) { - break; - } - } - if (!B) { - return ( rTS ? 0 : 1 ); - } - xT = 0.0001; // xTolerance - lower = 0; upper = 1; - percent = (upper + lower) / 2; - x = B(percent).x; i = 0; - while (Math.abs(xTarget - x) > xT && i < 100) { - if (xTarget > x) { - lower = percent; - } else { - upper = percent; - } - percent = (upper + lower) / 2; - x = B(percent).x; - i++; - } - return B(percent).y; -}; - -_kp.physicsInOut = function(options) { - var friction; - options = options || {}; - friction = options.friction|| 500; - return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] } ] }); -}; + _kp.physicsBackOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0,"y":0}]},{"x":1,"y":1,"cp":[{"x":0.735+(friction/1000),"y":1.3}]}] }); + }; -_kp.physicsIn = function(options) { - var friction; - options = options || {}; - friction = options.friction|| 500; - return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 1, y: 1 } ] } ] }); -}; + _kp.physicsBackIn = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.28-(friction / 1000),"y":-0.6}]},{"x":1,"y":1,"cp":[{"x":1,"y":1}]}] }); + }; -_kp.physicsOut = function(options) { - var friction; - options = options || {}; - friction = options.friction|| 500; - return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0, y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] }] }); -}; - -_kp.physicsBackOut = function(options) { - var friction; - options = options || {}; - friction = options.friction|| 500; - return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0,"y":0}]},{"x":1,"y":1,"cp":[{"x":0.735+(friction/1000),"y":1.3}]}] }); -}; - -_kp.physicsBackIn = function(options) { - var friction; - options = options || {}; - friction = options.friction|| 500; - return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.28-(friction / 1000),"y":-0.6}]},{"x":1,"y":1,"cp":[{"x":1,"y":1}]}] }); -}; - -_kp.physicsBackInOut = function(options) { - var friction; - options = options || {}; - friction = options.friction|| 500; - return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.68-(friction / 1000),"y":-0.55}]},{"x":1,"y":1,"cp":[{"x":0.265+(friction / 1000),"y":1.45}]}] }); -}; \ No newline at end of file + _kp.physicsBackInOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.68-(friction / 1000),"y":-0.55}]},{"x":1,"y":1,"cp":[{"x":0.265+(friction / 1000),"y":1.45}]}] }); + }; +}); diff --git a/kute.js b/kute.js index 04a78fa..9541f85 100644 --- a/kute.js +++ b/kute.js @@ -4,23 +4,23 @@ */ (function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['KUTE'], factory); // AMD. Register as an anonymous module. + if (typeof define === 'function' && define.amd) { + define([], factory); // AMD. Register as an anonymous module. } else if (typeof exports == 'object') { module.exports = factory(); // Node, not strict CommonJS } else { - // Browser globals + // Browser globals root.KUTE = root.KUTE || factory(); } }(this, function () { - var K = K || {}, _tws = [], _t, _stk = false, // _stoppedTick // _tweens // KUTE, _tween, _tick, + var K = K || {}, _tws = [], _t, _stk = false, // _stoppedTick // _tweens // KUTE, _tween, _tick, _pf = getPrefix(), // prefix _rafR = _rafR || ((!('requestAnimationFrame' in window)) ? true : false), // is prefix required for requestAnimationFrame _pfT = _pfT || ((!('transform' in document.getElementsByTagName('div')[0].style)) ? true : false), // is prefix required for transform _pfB = _pfB || ((!('border-radius' in document.getElementsByTagName('div')[0].style)) ? true : false), // is prefix required for border-radius _tch = _tch || (('ontouchstart' in window || navigator.msMaxTouchPoints) || false), // support Touch? _ev = _ev || (_tch ? 'touchstart' : 'mousewheel'), //event to prevent on scroll - + _bd = document.body, _htm = document.getElementsByTagName('HTML')[0], _sct = (/webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? _bd : _htm), @@ -39,16 +39,16 @@ _brbr = _brbr || _pfB ? _pf + 'BorderBottomRightRadius' : 'borderBottomRightRadius', _raf = _raf || _rafR ? window[_pf + 'RequestAnimationFrame'] : window['requestAnimationFrame'], _caf = _caf || _rafR ? window[_pf + 'CancelAnimationFrame'] : window['cancelAnimationFrame'], - + //supported properties _cls = ['color', 'backgroundColor', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0) _sc = ['scrollTop', 'scroll'], //scroll, it has no default value, it's calculated on tween start _clp = ['clip'], // clip _op = ['opacity'], // opacity _rd = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'], // border radius px/any - _bm = ['top', 'left', 'right', 'bottom', - 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', - 'padding', 'margin', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight', 'marginTop','marginBottom', 'marginLeft', 'marginRight', + _bm = ['top', 'left', 'right', 'bottom', + 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', + 'padding', 'margin', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight', 'marginTop','marginBottom', 'marginLeft', 'marginRight', 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'], // dimensions / box model _tp = ['fontSize','lineHeight','letterSpacing'], // text properties _bg = ['backgroundPosition'], // background position @@ -64,22 +64,22 @@ if (_cls.indexOf(p) !== -1){ _d[p] = 'rgba(0,0,0,0)'; // _d[p] = {r:0,g:0,b:0,a:1}; } else if ( _rd.indexOf(p) !== -1 || _bm.indexOf(p) !== -1 || _tp.indexOf(p) !== -1) { - _d[p] = 0; + _d[p] = 0; } else if ( _bg.indexOf(p) !== -1 ){ _d[p] = [50,50]; } else if ( p === 'clip' ){ - _d[p] = [0,0,0,0]; + _d[p] = [0,0,0,0]; } else if ( p === 'translate3d' ){ _d[p] = [0,0,0]; } else if ( p === 'translate' ){ _d[p] = [0,0]; } else if ( p === 'rotate' || /X|Y|Z/.test(p) ){ - _d[p] = 0; + _d[p] = 0; } else if ( p === 'scale' || p === 'opacity' ){ - _d[p] = 1; + _d[p] = 1; } } - + //more internals K.getAll = function () { return _tws; }; K.removeAll = function () { _tws = []; }; @@ -106,16 +106,16 @@ _stk = false; return true; }; - + // internal stopTick - K.s = function () { + K.s = function () { if ( _stk === false ) { _caf(_t); _stk = true; _t = null; } }; - + //main methods K.to = function (el, to, o) { if ( o === undefined ) { o = {}; } @@ -136,8 +136,8 @@ var _o = o; _o.easing = _o && K.pe(_o.easing) || K.Easing.linear; - - var _vS = K.prP(f, false), + + var _vS = K.prP(f, false), _vE = K.prP(to, true), _tw = new K.Tween(_el, _vS, _vE, _o); return _tw; @@ -160,7 +160,7 @@ tv = v1 + (v2 - v1) * v, u = _end.unit, // checking array on every frame takes time so let's cache these - cls = _cls.indexOf(p) !== -1, + cls = _cls.indexOf(p) !== -1, bm = _tp.indexOf(p) !== -1 || _bm.indexOf(p) !== -1, rd = _rd.indexOf(p) !== -1 && !_isIE8, sc = _sc.indexOf(p) !== -1, @@ -168,7 +168,7 @@ clp = _clp.indexOf(p) !== -1, op = _op.indexOf(p) !== -1, tf = p === 'transform' && !_isIE8; - + //process styles by property / property type if ( rd ) { if (p === 'borderRadius') { @@ -181,53 +181,53 @@ css[_brbl] = tv + u; } else if (p === 'borderBottomRightRadius') { css[_brbr] = tv + u; - } - + } + } else if (tf) { var _tS = '', tP, rps, pps = 'perspective('+w._pp+'px) '; //transform style & property - + for (tP in _end) { var t1 = _start[tP], t2 = _end[tP]; - rps = _3d.indexOf(tP) !== -1 && !_isIE; + rps = _3d.indexOf(tP) !== -1 && !_isIE; if ( tP === 'translate' ) { var tls = '', ts = {}, ax; - + for (ax in t2){ var x1 = t1[ax].value || 0, x2 = t2[ax].value || 0, xu = t2[ax].unit || 'px'; - ts[ax] = x1===x2 ? x2+xu : (x1 + ( x2 - x1 ) * v) + xu; + ts[ax] = x1===x2 ? x2+xu : (x1 + ( x2 - x1 ) * v) + xu; } tls = t2.x ? 'translate(' + ts.x + ',' + ts.y + ')' : - 'translate3d(' + ts.translateX + ',' + ts.translateY + ',' + ts.translateZ + ')'; - - _tS = (_tS === '') ? tls : (tls + ' ' + _tS); + 'translate3d(' + ts.translateX + ',' + ts.translateY + ',' + ts.translateZ + ')'; + + _tS = (_tS === '') ? tls : (tls + ' ' + _tS); } else if ( tP === 'rotate' ) { var rt = '', rS = {}, rx; - + for ( rx in t2 ){ if ( t1[rx] ) { - var a1 = t1[rx].value, a2 = t2[rx].value, au = t2[rx].unit||'deg', + var a1 = t1[rx].value, a2 = t2[rx].value, au = t2[rx].unit||'deg', av = a1 + (a2 - a1) * v; rS[rx] = rx ==='z' ? 'rotate('+av+au+')' : rx + '(' + av + au + ') '; } } rt = t2.z ? rS.z : (rS.rotateX||'') + (rS.rotateY||'') + (rS.rotateZ||''); - - _tS = (_tS === '') ? rt : (_tS + ' ' + rt); + + _tS = (_tS === '') ? rt : (_tS + ' ' + rt); } else if (tP==='skew') { var sk = '', sS = {}; for ( var sx in t2 ){ if ( t1[sx] ) { - var s1 = t1[sx].value, s2 = t2[sx].value, su = t2[sx].unit||'deg', + var s1 = t1[sx].value, s2 = t2[sx].value, su = t2[sx].unit||'deg', sv = s1 + (s2 - s1) * v; sS[sx] = sx + '(' + sv + su + ') '; } } sk = (sS.skewX||'') + (sS.skewY||''); - _tS = (_tS === '') ? sk : (_tS + ' ' + sk); + _tS = (_tS === '') ? sk : (_tS + ' ' + sk); } else if (tP === 'scale') { var sc1 = t1.value, sc2 = t2.value, - s = sc1 + (sc2 - sc1) * v, scS = tP + '(' + s + ')'; + s = sc1 + (sc2 - sc1) * v, scS = tP + '(' + s + ')'; _tS = (_tS === '') ? scS : (_tS + ' ' + scS); } } @@ -237,45 +237,45 @@ for (c in v2) { if ( c !== 'a' ){ - _c[c] = parseInt(v1[c] + (v2[c] - v1[c]) * v)||0; + _c[c] = parseInt(v1[c] + (v2[c] - v1[c]) * v)||0; } else { _c[c] = (v1[c] && v2[c]) ? parseFloat(v1[c] + (v2[c] - v1[c]) * v) : null; - } + } } - + if ( w._hex ) { css[p] = K.rth( parseInt(_c.r), parseInt(_c.g), parseInt(_c.b) ); } else { - css[p] = !_c.a || _isIE8 ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')'; + css[p] = !_c.a || _isIE8 ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')'; } } else if ( bm ) { css[p] = tv+u; - } else if ( sc ) { + } else if ( sc ) { ets.scrollTop = v1 + ( v2 - v1 ) * v; - } else if ( bg ) { + } else if ( bg ) { var px1 = _start.x.v, px2 = _end.x.v, py1 = _start.y.v, py2 = _end.y.v, px = (px1 + ( px2 - px1 ) * v), pxu = '%', - py = (py1 + ( py2 - py1 ) * v), pyu = '%'; + py = (py1 + ( py2 - py1 ) * v), pyu = '%'; css[p] = px + pxu + ' ' + py + pyu; } else if ( clp ) { var h = 0, cl = []; for (h;h<4;h++){ var c1 = _start[h].v, c2 = _end[h].v, cu = _end[h].u || 'px'; cl[h] = ((c1 + ( c2 - c1 ) * v)) + cu; - } + } css[p] = 'rect('+cl+')'; } else if ( op ) { css[opp] = !_isIE8 ? tv : "alpha(opacity=" + parseInt(tv*100) + ")"; } } }; - + K.perspective = function (l,w) { if ( w._ppo !== undefined ) { l.style[_pfo] = w._ppo; } // element perspective origin - if ( w._ppp !== undefined ) { l.parentNode.style[_pfp] = w._ppp + 'px'; } // parent perspective + if ( w._ppp !== undefined ) { l.parentNode.style[_pfp] = w._ppp + 'px'; } // parent perspective if ( w._pppo !== undefined ) { l.parentNode.style[_pfo] = w._pppo; } // parent perspective origin }; - + K.Tween = function (_el, _vS, _vE, _o) { this._el = this._el || _el; // element animation is applied to this._dr = this._dr || _o&&_o.duration || 700; //duration @@ -290,11 +290,11 @@ this._dl = this._dl || _o&&_o.delay || 0; //delay this._sT = null; // startTime this.paused = false; //_paused - this._pST = null; //_pauseStartTime - this._pp = this._pp || _o.perspective; // perspective - this._ppo = this._ppo || _o.perspectiveOrigin; // perspective origin - this._ppp = this._ppp || _o.parentPerspective; // parent perspective - this._pppo = this._pppo || _o.parentPerspectiveOrigin; // parent perspective origin + this._pST = null; //_pauseStartTime + this._pp = this._pp || _o.perspective; // perspective + this._ppo = this._ppo || _o.perspectiveOrigin; // perspective origin + this._ppp = this._ppp || _o.parentPerspective; // parent perspective + this._pppo = this._pppo || _o.parentPerspectiveOrigin; // parent perspective origin this._rpr = this._rpr || _o.rpr || false; // internal option to process inline/computed style at start instead of init true/false this._hex = this._hex || _o.keepHex || false; // option to keep hex for color tweens true/false this._e = this._e || _o.easing; // _easing @@ -305,23 +305,23 @@ this._cC = _o&&_o.complete || null; // _on CompleteCallback this._pC = _o&&_o.pause || null; // _on PauseCallback this._rC = _o&&_o.play || null; // _on ResumeCallback - this._stC = _o&&_o.stop || null; // _on StopCallback + this._stC = _o&&_o.stop || null; // _on StopCallback this.repeat = this._r; // we cache the number of repeats to be able to put it back after all cycles finish }; - + var w = K.Tween.prototype; - + w.start = function (t) { this.scrollIn(); var f = {}; - + K.perspective(this._el,this); // apply the perspective - + if ( this._rpr ) { // on start we reprocess the valuesStart for TO() method f = this.prS(); this._vS = {}; this._vS = K.prP(f,false); - + for ( p in this._vS ) { if ( p === 'transform' && (p in this._vE) ){ for ( var sp in this._vS[p]) { @@ -336,10 +336,10 @@ } } } - if ( 'value' in this._vS[p][sp] && (!('value' in this._vE[p][sp])) ) { // 2nd level + if ( 'value' in this._vS[p][sp] && (!('value' in this._vE[p][sp])) ) { // 2nd level for ( var spp in this._vS[p][sp] ) { // scale if (!(spp in this._vE[p][sp])) { - this._vE[p][sp][spp] = this._vS[p][sp][spp]; // spp = unit | value + this._vE[p][sp][spp] = this._vS[p][sp][spp]; // spp = unit | value } } } @@ -347,12 +347,12 @@ } } } - + for ( p in this._vE ) { - this._vSR[p] = this._vS[p]; + this._vSR[p] = this._vS[p]; } - // now it's a good time to start + // now it's a good time to start K.add(this); this.playing = true; this.paused = false; @@ -362,7 +362,7 @@ if (!_t) K.t(); return this; }; - + //main worker, doing update on tick w.u = function(t) { t = t || window.performance.now(); @@ -375,49 +375,49 @@ var e = ( t - this._sT ) / this._dr; //elapsed e = e > 1 ? 1 : e; - + //render the CSS update K.r(this,this._e(e)); - + if (this._uC) { this._uC.call(); } - if (e === 1) { + if (e === 1) { if (this._r > 0) { - if ( this._r !== Infinity ) { this._r--; } - + if ( this._r !== Infinity ) { this._r--; } + if (this._y) { this.reversed = !this.reversed; this.reverse(); } // handle yoyo - + this._sT = (this._y && !this.reversed) ? t + this._rD : t; //set the right time for delay - return true; + return true; } else { - + if (this._cC) { this._cC.call(); } - - //stop preventing scroll when scroll tween finished + + //stop preventing scroll when scroll tween finished this.scrollOut(); var i = 0, ctl = this._cT.length; for (i; i < ctl; i++) { this._cT[i].start(this._sT + this._dr); } - + //stop ticking when finished - this.close(); + this.close(); return false; } } return true; }; - + w.stop = function () { if (!this.paused && this.playing) { K.remove(this); this.playing = false; this.paused = false; this.scrollOut(); - + if (this._stC !== null) { this._stC.call(); - } + } this.stopChainedTweens(); this.close(); } @@ -427,8 +427,8 @@ w.pause = function() { if (!this.paused && this.playing) { K.remove(this); - this.paused = true; - this._pST = window.performance.now(); + this.paused = true; + this._pST = window.performance.now(); if (this._pC !== null) { this._pC.call(); } @@ -436,13 +436,13 @@ return this; }; - w.play = function () { + w.play = function () { if (this.paused && this.playing) { this.paused = false; if (this._rC !== null) { this._rC.call(); - } - this._sT += window.performance.now() - this._pST; + } + this._sT += window.performance.now() - this._pST; K.add(this); if (!_t) K.t(); // restart ticking if stopped } @@ -456,13 +456,13 @@ for (var p in this._vE) { var tmp = this._vSR[p]; this._vSR[p] = this._vE[p]; - this._vE[p] = tmp; - this._vS[p] = this._vSR[p]; + this._vE[p] = tmp; + this._vS[p] = this._vSR[p]; } } - return this; + return this; }; - + w.chain = function () { this._cT = arguments; return this; }; w.stopChainedTweens = function () { @@ -471,14 +471,14 @@ this._cT[i].stop(); } }; - - w.scrollOut = function(){ //prevent scroll when tweening scroll + + w.scrollOut = function(){ //prevent scroll when tweening scroll if ( 'scroll' in this._vE || 'scrollTop' in this._vE ) { this.removeListeners(); document.body.removeAttribute('data-tweening'); } }; - + w.scrollIn = function(){ if ( 'scroll' in this._vE || 'scrollTop' in this._vE ) { if (!document.body.getAttribute('data-tweening') ) { @@ -487,7 +487,7 @@ } } }; - + w.addListeners = function () { document.addEventListener(_ev, K.preventScroll, false); }; @@ -495,57 +495,57 @@ w.removeListeners = function () { document.removeEventListener(_ev, K.preventScroll, false); }; - + w.prS = function () { //prepare valuesStart for .to() method var f = {}, el = this._el, to = this._vS, cs = this.gIS('transform'), deg = ['rotate','skew'], ax = ['X','Y','Z']; - + for (var p in to){ if ( _tf.indexOf(p) !== -1 ) { var r2d = (p === 'rotate' || p === 'translate' || p === 'scale'); if ( /translate/.test(p) && p !== 'translate' ) { - f['translate3d'] = cs['translate3d'] || _d[p]; + f['translate3d'] = cs['translate3d'] || _d[p]; } else if ( r2d ) { // 2d transforms - f[p] = cs[p] || _d[p]; + f[p] = cs[p] || _d[p]; } else if ( !r2d && /rotate|skew/.test(p) ) { // all angles for (var d=0; d<2; d++) { for (var a = 0; a<3; a++) { - var s = deg[d]+ax[a]; + var s = deg[d]+ax[a]; if (_tf.indexOf(s) !== -1 && (s in to) ) { f[s] = cs[s] || _d[s]; } } } } } else { - if ( _sc.indexOf(p) === -1 ) { - if (p === 'opacity' && _isIE8 ) { // handle IE8 opacity - var co = this.gCS('filter'); + if ( _sc.indexOf(p) === -1 ) { + if (p === 'opacity' && _isIE8 ) { // handle IE8 opacity + var co = this.gCS('filter'); f['opacity'] = typeof co === 'number' ? co : _d['opacity']; } else { f[p] = this.gCS(p) || _d[p]; } } else { f[p] = (el === null || el === undefined) ? (window.pageYOffset || _sct.scrollTop) : el.scrollTop; - } + } } } - for ( var p in cs ){ // also add to _vS values from previous tweens + for ( var p in cs ){ // also add to _vS values from previous tweens if ( _tf.indexOf(p) !== -1 && (!( p in to )) ) { - f[p] = cs[p] || _d[p]; - } + f[p] = cs[p] || _d[p]; + } } - return f; - }; - + return f; + }; + w.gIS = function(p) { // gIS = get transform style for element from cssText for .to() method, the sp is for transform property if (!this._el) return; // if the scroll applies to `window` it returns as it has no styling - var l = this._el, cst = l.style.cssText,//the cssText + var l = this._el, cst = l.style.cssText,//the cssText trsf = {}; //the transform object // if we have any inline style in the cssText attribute, usually it has higher priority - var css = cst.replace(/\s/g,'').split(';'), i=0, csl = css.length; + var css = cst.replace(/\s/g,'').split(';'), i=0, csl = css.length; for ( i; i 0) { self._r = self.repeat; } if (self._y && self.reversed===true) { self.reverse(); self.reversed = false; } self.playing = false; },100) }; - + // process properties - K.prP = function (t, e) { // process tween properties for .fromTo() method + K.prP = function (t, e) { // process tween properties for .fromTo() method var _st = {}, tr = e === true ? _tfE : _tfS, tl = e === true ? _tlE : _tlS, @@ -598,14 +598,14 @@ for (var x in t) { if (_tf.indexOf(x) !== -1) { - - if (x !== 'translate' && /translate/.test(x)) { //process translate3d - var ta = ['X', 'Y', 'Z'], f = 0; //coordinates // translate[x] = pp(x, t[x]); - for (f; f < 3; f++) { + if (x !== 'translate' && /translate/.test(x)) { //process translate3d + var ta = ['X', 'Y', 'Z'], f = 0; //coordinates // translate[x] = pp(x, t[x]); + + for (f; f < 3; f++) { var a = ta[f]; if ( /3d/.test(x) ) { - tl['translate' + a] = K.pp('translate' + a, t[x][f]); + tl['translate' + a] = K.pp('translate' + a, t[x][f]); } else { tl['translate' + a] = ('translate' + a in t) ? K.pp('translate' + a, t['translate' + a]) : { value: 0, unit: 'px' }; } @@ -613,15 +613,15 @@ tr['translate'] = tl; } else if ( x !== 'rotate' && /rotate|skew/.test(x)) { //process rotation - var ap = /rotate/.test(x) ? 'rotate' : 'skew', ra = ['X', 'Y', 'Z'], r = 0, - _rt = {}, _sk = {}, rt = ap === 'rotate' ? _rt : _sk; + var ap = /rotate/.test(x) ? 'rotate' : 'skew', ra = ['X', 'Y', 'Z'], r = 0, + _rt = {}, _sk = {}, rt = ap === 'rotate' ? _rt : _sk; for (r; r < 3; r++) { var v = ra[r]; if ( t[ap+v] !== undefined && x !== 'skewZ' ) { rt[ap+v] = K.pp(ap + v, t[ap+v]); } } - + tr[ap] = rt; } else if ( x === 'translate' || x === 'rotate' || x === 'scale' ) { //process 2d translation / rotation tr[x] = K.pp(x, t[x]); @@ -635,13 +635,13 @@ } return _st; }; - - // _cls _sc _op _bm _tp _bg _tf + + // _cls _sc _op _bm _tp _bg _tf K.pp = function(p, v) {//process single property if (_tf.indexOf(p) !== -1) { var t = p.replace(/X|Y|Z/, ''), tv; - if (p === 'translate3d') { - tv = v.split(','); + if (p === 'translate3d') { + tv = v.split(','); return { translateX : { value: K.truD(tv[0]).v, unit: K.truD(tv[0]).u }, translateY : { value: K.truD(tv[1]).v, unit: K.truD(tv[1]).u }, @@ -658,7 +658,7 @@ t2d.y = { value: K.truD(tv[1]).v, unit: K.truD(tv[1]).u } } else { t2d.x = { value: K.truD(tv).v, unit: K.truD(tv).u }, - t2d.y = { value: 0, unit: 'px' } + t2d.y = { value: 0, unit: 'px' } } return t2d; } else if (p === 'rotate') { @@ -681,36 +681,36 @@ if (_clp.indexOf(p) !== -1) { if ( v instanceof Array ){ return [ K.truD(v[0]), K.truD(v[1]), K.truD(v[2]), K.truD(v[3]) ]; - } else { + } else { var ci; if ( /rect/.test(v) ) { - ci = v.replace(/rect|\(|\)/g,'').split(/\s|\,/); + ci = v.replace(/rect|\(|\)/g,'').split(/\s|\,/); } else if ( /auto|none|initial/.test(v) ){ - ci = _d[p]; - } + ci = _d[p]; + } return [ K.truD(ci[0]), K.truD(ci[1]), K.truD(ci[2]), K.truD(ci[3]) ]; - } + } } if (_cls.indexOf(p) !== -1) { return { value: K.truC(v) }; } if (_bg.indexOf(p) !== -1) { - if ( v instanceof Array ){ + if ( v instanceof Array ){ return { x: K.truD(v[0])||{ v: 50, u: '%' }, y: K.truD(v[1])||{ v: 50, u: '%' } }; } else { var posxy = v.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/,50).split(/\s|\,/g), xp = K.truD(posxy[0]), yp = K.truD(posxy[1]); return { x: xp, y: yp }; - } + } } if (_rd.indexOf(p) !== -1) { var rad = K.truD(v); return { value: rad.v, unit: rad.u }; } }; - + K.truD = function (d,p) { //true dimension returns { v = value, u = unit } - var x = parseInt(d) || 0, mu = ['px','%','deg','rad','em','rem','vh','vw'], l = mu.length, + var x = parseInt(d) || 0, mu = ['px','%','deg','rad','em','rem','vh','vw'], l = mu.length, y = getU(); function getU() { var u,i=0; @@ -720,14 +720,14 @@ } return { v: x, u: y }; }; - + K.preventScroll = function (e) { // prevent mousewheel or touch events while tweening scroll var data = document.body.getAttribute('data-tweening'); if (data && data === 'scroll') { e.preventDefault(); } }; - + K.truC = function (v) { // replace transparent and transform any color to rgba()/rgb() var vrgb, y; if (/rgb|rgba/.test(v)) { //rgb will be fastest initialized @@ -745,7 +745,7 @@ return { r: 0, g: 0, b: 0, a: 0 }; } }; - + K.rth = function (r, g, b) { // transform rgb to hex or vice-versa | webkit browsers ignore HEX, always use RGB/RGBA return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); }; @@ -762,34 +762,34 @@ g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; - }; - + }; + K.pe = function (es) { //process easing if ( typeof es === 'function') { return es; } else if ( typeof es === 'string' ) { if ( /easing|linear/.test(es) ) { return K.Easing[es]; //regular Robert Penner Easing Functions - } else if ( /bezier/.test(es) ) { + } else if ( /bezier/.test(es) ) { var bz = es.replace(/bezier|\s|\(|\)/g,'').split(','), i = 0, l = bz.length; for (i; i