﻿/*
Javascript 补间动画操作
sun.Lei 2010.7
算法来自 actionscript 2.0(http://www.robertpenner.com/easing/),感谢cloudgamer提供资料来源
*/

(function (w) { if (typeof (Lei) != "object") { alert('提醒:Tween功能需要依赖Lei.Common.js库!') }; var _t_ = { Linear: function (t, b, c, d) { return c * t / d + b }, Quad: { easeIn: function (t, b, c, d) { return c * (t /= d) * t + b }, easeOut: function (t, b, c, d) { return -c * (t /= d) * (t - 2) + b }, easeInOut: function (t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t + b; return -c / 2 * ((--t) * (t - 2) - 1) + b } }, Cubic: { easeIn: function (t, b, c, d) { return c * (t /= d) * t * t + b }, easeOut: function (t, b, c, d) { return c * ((t = t / d - 1) * t * t + 1) + b }, easeInOut: function (t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t + b; return c / 2 * ((t -= 2) * t * t + 2) + b } }, Quart: { easeIn: function (t, b, c, d) { return c * (t /= d) * t * t * t + b }, easeOut: function (t, b, c, d) { return -c * ((t = t / d - 1) * t * t * t - 1) + b }, easeInOut: function (t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b; return -c / 2 * ((t -= 2) * t * t * t - 2) + b } }, Quint: { easeIn: function (t, b, c, d) { return c * (t /= d) * t * t * t * t + b }, easeOut: function (t, b, c, d) { return c * ((t = t / d - 1) * t * t * t * t + 1) + b }, easeInOut: function (t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b; return c / 2 * ((t -= 2) * t * t * t * t + 2) + b } }, Sine: { easeIn: function (t, b, c, d) { return -c * Math.cos(t / d * (Math.PI / 2)) + c + b }, easeOut: function (t, b, c, d) { return c * Math.sin(t / d * (Math.PI / 2)) + b }, easeInOut: function (t, b, c, d) { return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b } }, Expo: { easeIn: function (t, b, c, d) { return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b }, easeOut: function (t, b, c, d) { return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b }, easeInOut: function (t, b, c, d) { if (t == 0) return b; if (t == d) return b + c; if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b; return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b } }, Circ: { easeIn: function (t, b, c, d) { return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b }, easeOut: function (t, b, c, d) { return c * Math.sqrt(1 - (t = t / d - 1) * t) + b }, easeInOut: function (t, b, c, d) { if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b } }, Elastic: { easeIn: function (t, b, c, d, a, p) { if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; if (!a || a < Math.abs(c)) { a = c; var s = p / 4 } else var s = p / (2 * Math.PI) * Math.asin(c / a); return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b }, easeOut: function (t, b, c, d, a, p) { if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; if (!a || a < Math.abs(c)) { a = c; var s = p / 4 } else var 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) }, easeInOut: function (t, b, c, d, a, p) { if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5); if (!a || a < Math.abs(c)) { a = c; var s = p / 4 } else var s = p / (2 * Math.PI) * Math.asin(c / a); if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b } }, Back: { easeIn: function (t, b, c, d, s) { if (s == undefined) s = 1.70158; return c * (t /= d) * t * ((s + 1) * t - s) + b }, easeOut: function (t, b, c, d, s) { if (s == undefined) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b }, easeInOut: function (t, b, c, d, s) { if (s == undefined) s = 1.70158; if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b } }, Bounce: { easeIn: function (t, b, c, d) { return c - _t_.Bounce.easeOut(d - t, 0, c, d) + b }, easeOut: 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 + .75) + b } else if (t < (2.5 / 2.75)) { return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b } else { return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b } }, easeInOut: function (t, b, c, d) { if (t < d / 2) return _t_.Bounce.easeIn(t * 2, 0, c, d) * .5 + b; else return _t_.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b } } }; var Tween = Lei.Object.Create(); Tween.prototype = { init: function (obj, attributes, options) { if (typeof (obj) == "string") obj = Lei.$(obj); this.obj = obj; this.setOptions(options); this.startAttr = []; this.endAttr = []; if (typeof (attributes) != "object") return; this.attributes = this.getAttributes(attributes); this.timer = null }, setOptions: function (arg) { this.options = { currentTime: 0, duration: 100, tweenType: "Linear", easeType: "easeIn", onStart: null, onEnd: null }; Lei.Object.Extend(this.options, arg || {}) }, getAttributes: function (attributes) { for (var attr in attributes) { switch (attr) { case 'color': case 'borderColor': case 'border-color': case 'backgroundColor': case 'background-color': this.startAttr[attr] = parseColor(attributes[attr].from || Lei.Utils.getStyle(this.obj, attr)); this.endAttr[attr] = parseColor(attributes[attr].to); break; case 'scrollTop': case 'scrollLeft': var obj = (this.obj == document.body) ? (document.documentElement || document.body) : this.obj; this.startAttr[attr] = attributes[attr].from || el[attr]; this.endAttr[attr] = attributes[attr].to; break; default: var start, end = attributes[attr].to; if (!!attributes[attr].from) { start = attributes[attr].from } else { start = parseFloat(Lei.Utils.getStyle(this.obj, attr)) || 0 } this.startAttr[attr] = start; this.endAttr[attr] = end; break } } }, play: function () { var p = this; this.options.currentTime = new Date().getTime(); var t = 0; var d = this.options.duration; var b, b1, c, v, _t, f; var isexec = false; if (this.options.tweenType == "Linear") { _t = _t_.Linear } else { _t = _t_[this.options.tweenType][this.options.easeType] }; if (_t == null) return; if (Lei.isFunction(this.options.onStart)) { this.options.onStart(p.obj) }; this.timer = w.setInterval(function () { for (var attr in p.startAttr) { if (t < d) { t++; b = p.startAttr[attr]; b1 = p.endAttr[attr]; if (b instanceof Array) { if (b.length == 3) { v = 'rgb('; v += Math.floor(_t(t, Math.floor(b[0]), Math.floor(b1[0]) - Math.floor(b[0]), d)); v += ','; v += Math.floor(_t(t, Math.floor(b[1]), Math.floor(b1[1]) - Math.floor(b[1]), d)); v += ','; v += Math.floor(_t(t, Math.floor(b[2]), Math.floor(b1[2]) - Math.floor(b[2]), d)); v += ')' } } else { c = b1 - b; if (c == 0) continue; f = _t(t, b, c, d); if (attr.toLowerCase() == "opacity") { v = f } else if ("width,height".indexOf(attr.toLowerCase()) > -1) { if (f < 0) f = 0; v = Math.ceil(f) + "px" } else { v = Math.ceil(f) + "px" } }; Lei.Utils.setStyle(p.obj, attr, v) } else { w.clearInterval(p.timer); p.timer = null; Lei.Utils.setStyle(p.obj, attr, p.endAttr[attr]); if (!isexec) { isexec = true; if (Lei.isFunction(p.options.onEnd)) { p.options.onEnd(p.obj) } } } } }, 10) } }; var parseColor = (function () { var hex6 = (/^#?(\w{2})(\w{2})(\w{2})$/); var hex3 = (/^#?(\w{1})(\w{1})(\w{1})$/); var rgb = (/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/); return function (str) { var color = str.match(hex6); if (color && color.length == 4) { return [parseInt(color[1], 16), parseInt(color[2], 16), parseInt(color[3], 16)] }; color = str.match(rgb); if (color && color.length == 4) { return [parseInt(color[1], 10), parseInt(color[2], 10), parseInt(color[3], 10)] }; color = str.match(hex3); if (color && color.length == 4) { return [parseInt(color[1] + color[1], 16), parseInt(color[2] + color[2], 16), parseInt(color[3] + color[3], 16)] } } })(); Lei.Tween = Tween; Lei.Tween.Lib = _t_ })(window);

