Changeset View
Changeset View
Standalone View
Standalone View
externals/javelin/src/ext/fx/FX.js
- This file was added.
| /** | |||||
| * @provides javelin-fx | |||||
| * @requires javelin-color javelin-install javelin-util | |||||
| * @javelin | |||||
| * | |||||
| * Based on moo.fx (moofx.mad4milk.net). | |||||
| */ | |||||
| JX.install('FX', { | |||||
| events: ['start', 'complete'], | |||||
| construct: function(element) { | |||||
| this._config = {}; | |||||
| this.setElement(element); | |||||
| this.setTransition(JX.FX.Transitions.sine); | |||||
| }, | |||||
| properties: { | |||||
| fps: 50, | |||||
| wait: true, | |||||
| duration: 500, | |||||
| element: null, | |||||
| property: null, | |||||
| transition: null | |||||
| }, | |||||
| members: { | |||||
| _to: null, | |||||
| _now: null, | |||||
| _from: null, | |||||
| _start: null, | |||||
| _config: null, | |||||
| _interval: null, | |||||
| start: function(config) { | |||||
| if (__DEV__) { | |||||
| if (!config) { | |||||
| throw new Error('What styles do you want to animate?'); | |||||
| } | |||||
| if (!this.getElement()) { | |||||
| throw new Error('What element do you want to animate?'); | |||||
| } | |||||
| } | |||||
| if (this._interval && this.getWait()) { | |||||
| return; | |||||
| } | |||||
| var from = {}; | |||||
| var to = {}; | |||||
| for (var prop in config) { | |||||
| from[prop] = config[prop][0]; | |||||
| to[prop] = config[prop][1]; | |||||
| if (/color/i.test(prop)) { | |||||
| from[prop] = JX.Color.hexToRgb(from[prop], true); | |||||
| to[prop] = JX.Color.hexToRgb(to[prop], true); | |||||
| } | |||||
| } | |||||
| this._animate(from, to); | |||||
| return this; | |||||
| }, | |||||
| stop: function() { | |||||
| clearInterval(this._interval); | |||||
| this._interval = null; | |||||
| return this; | |||||
| }, | |||||
| then: function(func) { | |||||
| var token = this.listen('complete', function() { | |||||
| token.remove(); | |||||
| func(); | |||||
| }); | |||||
| return this; | |||||
| }, | |||||
| _animate: function(from, to) { | |||||
| if (!this.getWait()) { | |||||
| this.stop(); | |||||
| } | |||||
| if (this._interval) { | |||||
| return; | |||||
| } | |||||
| setTimeout(JX.bind(this, this.invoke, 'start'), 10); | |||||
| this._from = from; | |||||
| this._to = to; | |||||
| this._start = JX.now(); | |||||
| this._interval = setInterval( | |||||
| JX.bind(this, this._tween), | |||||
| Math.round(1000 / this.getFps())); | |||||
| }, | |||||
| _tween: function() { | |||||
| var now = JX.now(); | |||||
| var prop; | |||||
| if (now < this._start + this.getDuration()) { | |||||
| this._now = now - this._start; | |||||
| for (prop in this._from) { | |||||
| this._config[prop] = this._compute(this._from[prop], this._to[prop]); | |||||
| } | |||||
| } else { | |||||
| setTimeout(JX.bind(this, this.invoke, 'complete'), 10); | |||||
| // Compute the final position using the transition function, in case | |||||
| // the function applies transformations. | |||||
| this._now = this.getDuration(); | |||||
| for (prop in this._from) { | |||||
| this._config[prop] = this._compute(this._from[prop], this._to[prop]); | |||||
| } | |||||
| this.stop(); | |||||
| } | |||||
| this._render(); | |||||
| }, | |||||
| _compute: function(from, to) { | |||||
| if (JX.isArray(from)) { | |||||
| return from.map(function(value, ii) { | |||||
| return Math.round(this._compute(value, to[ii])); | |||||
| }, this); | |||||
| } | |||||
| var delta = to - from; | |||||
| return this.getTransition()(this._now, from, delta, this.getDuration()); | |||||
| }, | |||||
| _render: function() { | |||||
| var style = this.getElement().style; | |||||
| for (var prop in this._config) { | |||||
| var value = this._config[prop]; | |||||
| if (prop == 'opacity') { | |||||
| value = parseInt(100 * value, 10); | |||||
| if (window.ActiveXObject) { | |||||
| style.filter = 'alpha(opacity=' + value + ')'; | |||||
| } else { | |||||
| style.opacity = value / 100; | |||||
| } | |||||
| } else if (/color/i.test(prop)) { | |||||
| style[prop] = 'rgb(' + value + ')'; | |||||
| } else { | |||||
| style[prop] = value + 'px'; | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| statics: { | |||||
| fade: function(element, visible) { | |||||
| return new JX.FX(element).setDuration(250).start({ | |||||
| opacity: visible ? [0, 1] : [1, 0] | |||||
| }); | |||||
| }, | |||||
| highlight: function(element, color) { | |||||
| color = color || '#fff8dd'; | |||||
| return new JX.FX(element).setDuration(1000).start({ | |||||
| backgroundColor: [color, '#fff'] | |||||
| }); | |||||
| }, | |||||
| /** | |||||
| * Easing equations based on work by Robert Penner | |||||
| * http://www.robertpenner.com/easing/ | |||||
| */ | |||||
| Transitions: { | |||||
| linear: function(t, b, c, d) { | |||||
| return c * t / d + b; | |||||
| }, | |||||
| sine: function(t, b, c, d) { | |||||
| return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; | |||||
| }, | |||||
| sineIn: function(t, b, c, d) { | |||||
| if (t == d) { | |||||
| return c + b; | |||||
| } | |||||
| return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; | |||||
| }, | |||||
| sineOut: function(t, b, c, d) { | |||||
| if (t == d) { | |||||
| return c + b; | |||||
| } | |||||
| return c * Math.sin(t / d * (Math.PI / 2)) + b; | |||||
| }, | |||||
| elastic: function(t, b, c, d, a, p) { | |||||
| if (t === 0) { return b; } | |||||
| if ((t /= d) == 1) { return b + c; } | |||||
| if (!p) { p = d * 0.3; } | |||||
| if (!a) { a = 1; } | |||||
| var s; | |||||
| if (a < Math.abs(c)) { | |||||
| a = c; | |||||
| s = p / 4; | |||||
| } else { | |||||
| s = p / (2 * Math.PI) * Math.asin(c / a); | |||||
| } | |||||
| return a * Math.pow(2, -10 * t) * | |||||
| Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b; | |||||
| }, | |||||
| bounce: function(t, b, c, d) { | |||||
| if ((t /= d) < (1 / 2.75)) { | |||||
| return c * (7.5625 * t * t) + b; | |||||
| } else if (t < (2 / 2.75)) { | |||||
| return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; | |||||
| } else if (t < (2.5 / 2.75)) { | |||||
| return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; | |||||
| } else { | |||||
| return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| }); | |||||