Last active
August 29, 2015 14:10
-
-
Save maolion/73f1f1a5d4142ac40b44 to your computer and use it in GitHub Desktop.
Animation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// @require ../libs/jQuery/jquery.easing.1.3.js | |
| var | |
| Utils = require("./Utils.js"), | |
| Env = require("./Env.js"), | |
| Event = require("./Event.js"), | |
| own = Object.prototype.hasOwnProperty, | |
| slice = Array.prototype.slice | |
| ; | |
| var | |
| PLAY_STATE_NONE = 0, | |
| PLAY_STATE_RUNNING = 1, | |
| PLAY_STATE_PAUSED = 2, | |
| PLAY_STATE_DONE = 3 | |
| ; | |
| var | |
| transitions = { | |
| linear : 'linear', | |
| ease : 'ease', | |
| easeIn : 'ease-in', | |
| easeOut : 'ease-out', | |
| easeInOut : 'ease-in-out', | |
| easeInSine : 'cubic-bezier(0.47, 0, 0.745, 0.715)', | |
| easeOutSine : 'cubic-bezier(0.39, 0.575, 0.565, 1)', | |
| easeInOutSine : 'cubic-bezier(0.445, 0.05, 0.55, 0.95)', | |
| easeInQuad : 'cubic-bezier(0.55, 0.085, 0.68, 0.53)', | |
| easeOutQuad : 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', | |
| easeInOutQuad : 'cubic-bezier(0.455, 0.03, 0.515, 0.955)', | |
| easeInCubic : 'cubic-bezier(0.55, 0.055, 0.675, 0.19)', | |
| easeOutCubic : 'cubic-bezier(0.215, 0.61, 0.355, 1)', | |
| easeInOutCubic : 'cubic-bezier(0.645, 0.045, 0.355, 1)', | |
| easeInQuart : 'cubic-bezier(0.895, 0.03, 0.685, 0.22)', | |
| easeOutQuart : 'cubic-bezier(0.165, 0.84, 0.44, 1)', | |
| easeInOutQuart : 'cubic-bezier(0.77, 0, 0.175, 1)', | |
| easeInQuint : 'cubic-bezier(0.755, 0.05, 0.855, 0.06)', | |
| easeOutQuint : 'cubic-bezier(0.23, 1, 0.32, 1)', | |
| easeInOutQuint : 'cubic-bezier(0.86, 0, 0.07, 1)', | |
| easeInExpo : 'cubic-bezier(0.95, 0.05, 0.795, 0.035)', | |
| easeOutExpo : 'cubic-bezier(0.19, 1, 0.22, 1)', | |
| easeInOutExpo : 'cubic-bezier(1, 0, 0, 1)', | |
| easeInCirc : 'cubic-bezier(0.6, 0.04, 0.98, 0.335)', | |
| easeOutCirc : 'cubic-bezier(0.075, 0.82, 0.165, 1)', | |
| easeInOutCirc : 'cubic-bezier(0.785, 0.135, 0.15, 0.86)', | |
| easeInBack : 'cubic-bezier(0.6, -0.28, 0.735, 0.045)', | |
| easeOutBack : 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', | |
| easeInOutBack : 'cubic-bezier(0.68, -0.55, 0.265, 1.55)' | |
| } | |
| ; | |
| function Animate(opt){ | |
| var _this = this; | |
| Event.call(this); | |
| this.el = opt.element instanceof jQuery ? opt.element : jQuery(opt.element||document.body); | |
| this.elStyle = this.el[0].style; | |
| this.duration = opt.duration || 400; | |
| this.delay = Math.max(~~opt.delay, 0); | |
| this.timing = opt.timing || 'ease'; | |
| this.fillMode = opt.fillMode || 'forwards'; | |
| this.to = opt.to ? getCompatibilityStyle(opt.to) : {}; | |
| this.from = opt.from ? getCompatibilityStyle(opt.from) : {}; | |
| this.playState = PLAY_STATE_NONE; | |
| this.startTime = 0; | |
| this.currentTime = 0; | |
| this.timer = null; | |
| jQuery.each(['onStart', 'onPaused', 'onEnd'], function(index, event){ | |
| if (opt[event] instanceof Function) { | |
| _this[event] = opt[event]; | |
| } | |
| }); | |
| if (Env.CSS_SUPPORT.ANIMATE) { | |
| this.timing = transitions[this.timing] || this.timing || 'ease'; | |
| this.property = function(){ | |
| var keys = []; | |
| for(var k in _this.to) { | |
| if (own.call(_this.to, k)) keys.push(toNormalizationtyleProperty(k)); | |
| } | |
| return keys.join(","); | |
| }(); | |
| this.el.on("webkitTransitionEnd transitionend", function(){ | |
| if (_this.playState !== PLAY_STATE_RUNNING) return; | |
| _this.end(); | |
| }); | |
| } else { | |
| this.animateDoneHandler = function(){ | |
| _this.end(); | |
| }; | |
| this.timing = own.call(jQuery.easing, this.timing) ? this.timing : 'swing'; | |
| } | |
| }; | |
| var api = Animate.prototype = Utils.create(Event.prototype, Animate); | |
| api.onStart = | |
| api.onPaused = | |
| api.onEnd = jQuery.noop; | |
| [ | |
| function(){ | |
| api.play = function(){ | |
| var _this = this; | |
| switch(this.playState) { | |
| case PLAY_STATE_NONE: | |
| case PLAY_STATE_DONE: | |
| _this.timer = setTimeout(function(){ | |
| _this.playState = PLAY_STATE_RUNNING; | |
| _this.currentTime = 0; | |
| _this.startTime = new Date().getTime(); | |
| _this.el.stop() | |
| .css(_this.from) | |
| .animate(_this.to, _this.duration, _this.timing, _this.animateDoneHandler) | |
| ; | |
| _this.onStart(); | |
| _this.fireEvent("start"); | |
| }, this.delay); | |
| break; | |
| case PLAY_STATE_PAUSED: | |
| this.startTime = new Date().getTime(); | |
| this.playState = PLAY_STATE_RUNNING; | |
| this.el.stop() | |
| .animate(this.to, this.duration, this.timing, this.animateDoneHandler) | |
| ; | |
| this.onStart(); | |
| this.fireEvent("start"); | |
| break; | |
| } | |
| }; | |
| api.pause = function(){ | |
| clearTimeout(this.timer); | |
| if (this.playState !== PLAY_STATE_RUNNING) return; | |
| this.currentTime += new Date().getTime() - this.startTime; | |
| this.el.stop(); | |
| this.playState = PLAY_STATE_PAUSED; | |
| this.onPaused(); | |
| this.fireEvent("paused"); | |
| }; | |
| api.end = function(){ | |
| if (this.playState === PLAY_STATE_DONE) return; | |
| this.el.stop(); | |
| if (this.fillMode === 'forwards') { | |
| if (this.playState === PLAY_STATE_PAUSED || this.currentTime + (new Date() - this.startTime) < this.duration) { | |
| this.el.css(this.to); | |
| } | |
| } else { | |
| this.el.css(this.from); | |
| } | |
| this.playState = PLAY_STATE_DONE; | |
| this.currentTime = this.duration; | |
| this.onEnd(); | |
| this.fireEvent("end"); | |
| }; | |
| }, | |
| function(){ | |
| api.play = function(){ | |
| var _this = this; | |
| switch(this.playState) { | |
| case PLAY_STATE_NONE: | |
| case PLAY_STATE_DONE: | |
| this.elStyle[Env.CSSPROP.transitionDuration] = '0ms'; | |
| this.elStyle[Env.CSSPROP.transitionTimingFunction] = this.timing; | |
| this.elStyle[Env.CSSPROP.transitionProperty] = this.property; | |
| _this.timer = setTimeout(function(){ | |
| setStyle(_this.elStyle, _this.from); | |
| _this.timer = setTimeout(function(){ | |
| _this.playState = PLAY_STATE_RUNNING; | |
| _this.currentTime = 0; | |
| _this.startTime = new Date().getTime(); | |
| _this.elStyle[Env.CSSPROP.transitionDuration] = _this.duration + 'ms'; | |
| setStyle(_this.elStyle, _this.to); | |
| _this.onStart(); | |
| _this.fireEvent("start"); | |
| }, 16); | |
| }, this.delay); | |
| break; | |
| case PLAY_STATE_PAUSED: | |
| _this.startTime = new Date().getTime(); | |
| this.playState = PLAY_STATE_RUNNING; | |
| this.elStyle[Env.CSSPROP.transitionDuration] = (this.duration - this.currentTime) + 'ms'; | |
| setStyle(this.elStyle, this.to); | |
| this.onStart(); | |
| this.fireEvent("start"); | |
| break; | |
| } | |
| }; | |
| api.pause = function(){ | |
| clearTimeout(this.timer); | |
| if (this.playState !== PLAY_STATE_RUNNING) return; | |
| this.currentTime += new Date().getTime() - this.startTime; | |
| this.elStyle[Env.CSSPROP.transitionDuration] = '0ms'; | |
| var cStyle = window.getComputedStyle(this.el[0], null); | |
| for(var k in this.to) { | |
| if (!own.call(this.to, k)) continue; | |
| this.elStyle[k] = cStyle[k]; | |
| } | |
| this.playState = PLAY_STATE_PAUSED; | |
| this.onPaused(); | |
| this.fireEvent("paused"); | |
| }; | |
| api.end = function(){ | |
| if (this.playState === PLAY_STATE_DONE) return; | |
| this.elStyle[Env.CSSPROP.transition] = 'none'; | |
| if (this.fillMode === 'forwards') { | |
| if (this.playState === PLAY_STATE_PAUSED || this.currentTime + (new Date() - this.startTime) < this.duration) { | |
| setStyle(this.elStyle, this.to); | |
| } | |
| } else { | |
| setStyle(this.elStyle, this.from); | |
| } | |
| this.playState = PLAY_STATE_DONE; | |
| this.currentTime = this.duration; | |
| this.onEnd(); | |
| this.fireEvent("end"); | |
| }; | |
| } | |
| ][+Env.CSS_SUPPORT.ANIMATE](); | |
| function getCompatibilityStyle(style) { | |
| var | |
| r = {} | |
| ; | |
| if (Env.CSS_SUPPORT.ANIMATE) { | |
| var re = /^\*/; | |
| style = style.CSS3 || style; | |
| for(var k in style) { | |
| if (!own.call(style, k)) continue; | |
| r[toJsStyleProperty(k.replace(re, Env.CSS_VENDOR))] = style[k]; | |
| } | |
| } else { | |
| delete style.CSS3; | |
| for(var k in style) { | |
| if (!own.call(style, k)) continue; | |
| r[toJsStyleProperty(k)] = style[k]; | |
| } | |
| } | |
| return r; | |
| }; | |
| function toJsStyleProperty(name){ | |
| var | |
| name = name.split('-'), | |
| n = 0 | |
| ; | |
| for(var i = 0, l = name.length; i < l; i++) { | |
| var p = name[i]; | |
| if (!p) continue; | |
| name[n] = n === 0 ? p : p.charAt(0).toUpperCase() + p.slice(1); | |
| n++; | |
| } | |
| name.length = n; | |
| return name.join(""); | |
| } | |
| function toNormalizationtyleProperty(name){ | |
| name = name.replace(/([A-Z])/g, function(match, $1){ | |
| return '-' + $1.toLowerCase() | |
| }); | |
| if (/^(?:webkit|moz|ms|o)-/.test(name)) { | |
| name = '-' + name; | |
| } | |
| return name; | |
| } | |
| function setStyle(style, css) { | |
| for(var k in css) { | |
| style[k] = css[k]; | |
| } | |
| } | |
| //x = new Animate({ | |
| // element : '#akd_logo', | |
| // duration : 5000, | |
| // fillMode : 'backwards', | |
| // to : { | |
| // left : 10, | |
| // width : 100, | |
| // CSS3 : { | |
| // '*transform' : 'translateX(10px)', | |
| // width : '100px' | |
| // } | |
| // }, | |
| // from : { | |
| // left : 50, | |
| // width : 200, | |
| // CSS3 : { | |
| // '*transform' : 'translateX(50px)', | |
| // width : '200px' | |
| // } | |
| // } | |
| //}); | |
| //x.onStart = function(){ | |
| // console.log("start"); | |
| //}; | |
| //x.onDone = function(){ | |
| // console.log("done"); | |
| // x.play(); | |
| //}; | |
| //x.onPaused = function(){ | |
| // console.log("paused"); | |
| //}; | |
| //x.play(); | |
| function Animation(){ | |
| Event.call(this); | |
| var | |
| _this = this, | |
| animates = slice.call(arguments), | |
| n = 0 | |
| ; | |
| jQuery.each(animates, function(index, animate){ | |
| if (!animate || !(animate instanceof Object)) return; | |
| animate = animates[index = n++] = animate instanceof Animation ? animate : new Animate(animate); | |
| animate.on("end", function(){ | |
| if (index + 1 >= _this._count) { | |
| _this.end(); | |
| return; | |
| } | |
| animates[_this._currentIndex = index+1].play(); | |
| }); | |
| }); | |
| animates.length = n; | |
| this._animates = animates; | |
| this._currentIndex = 0; | |
| this._count = animates.length; | |
| this._playState = PLAY_STATE_NONE; | |
| }; | |
| var api = Animation.prototype = Utils.create(Event.prototype, Animation); | |
| api.onStart = | |
| api.onPaused = | |
| api.onEnd = jQuery.noop; | |
| api.play = function() { | |
| if (!this._count) return; | |
| switch(this._playState) { | |
| case PLAY_STATE_NONE: | |
| case PLAY_STATE_DONE: | |
| this._currentIndex = 0; | |
| this._animates[0].play(); | |
| this._playState = PLAY_STATE_RUNNING; | |
| this.onStart(); | |
| this.fireEvent("start"); | |
| break; | |
| case PLAY_STATE_PAUSED: | |
| this._animates[this._currentIndex].play(); | |
| this.onStart(); | |
| this.fireEvent("start"); | |
| break; | |
| } | |
| }; | |
| api.pause = function(){ | |
| if (!this._count) return; | |
| if (this._playState === PLAY_STATE_PAUSED) return; | |
| this._animates[this._currentIndex].pause(); | |
| this.onPaused(); | |
| this.fireEvent("paused"); | |
| }; | |
| api.end = function(){ | |
| if (!this._count) return; | |
| if (this._playState === PLAY_STATE_DONE) return; | |
| for(var i = this._animates.length; --i>=0;) this._animates[i].end(); | |
| this._currentIndex = this._count - 1; | |
| this._playState = PLAY_STATE_DONE; | |
| this.onEnd(); | |
| this.fireEvent("end"); | |
| }; | |
| api.isRunning = function() { | |
| return this._playState === PLAY_STATE_RUNNING; | |
| }; | |
| api.isPaused = function(){ | |
| return this._playState === PLAY_STATE_PAUSED; | |
| }; | |
| api.isDone = function(){ | |
| return this._playState === PLAY_STATE_DONE; | |
| }; | |
| module.exports = Animation; | |
| //example | |
| jQuery('#akd_logo').css('webkitAnimation', 'none'); | |
| x = new Animation( | |
| { | |
| element : '#akd_logo', | |
| duration : 1200, | |
| from : { | |
| top : '50%', | |
| opacity : 1, | |
| CSS3 : { | |
| '*transform' : 'translateY(0)', | |
| opacity : 1 | |
| } | |
| }, | |
| to : { | |
| top : '20%', | |
| opacity : 0, | |
| CSS3 : { | |
| '*transform' : 'translateY(-200px)', | |
| opacity : 0 | |
| } | |
| }, | |
| onStart : function() { | |
| console.log("a"); | |
| } | |
| }, | |
| { | |
| element : '#akd_logo', | |
| duration : 2000, | |
| timing : 'easeOutBack', | |
| from : { | |
| top : '80%', | |
| opacity : 0, | |
| CSS3 : { | |
| '*transform' : 'translateY(200px)', | |
| opacity : 0 | |
| } | |
| }, | |
| to : { | |
| top : '50%', | |
| opacity : 1, | |
| CSS3 : { | |
| '*transform' : 'translateY(0)', | |
| opacity : 1 | |
| } | |
| }, | |
| onStart : function(){ | |
| console.log("b"); | |
| } | |
| } | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment