Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

开始重构fx模块

  • Loading branch information...
commit eb801c41c4c0e5beba48ae26cec49576fb66aceb 1 parent eed886d
@RubyLouvre authored
Showing with 151 additions and 146 deletions.
  1. +151 −146 fx.js
View
297 fx.js
@@ -6,9 +6,9 @@ define("fx", ["css"], function($) {
color: /color/i,
scroll: /scroll/i
},
- rfxnum = /^([+\-/*]=)?([\d+.\-]+)([a-z%]*)$/i,
- timeline = $.timeline = []; //时间轴
- $.mix({ //缓动公式
+ rfxnum = /^([+\-/*]=)?([\d+.\-]+)([a-z%]*)$/i,
+ timeline = $.timeline = []; //时间轴
+ $.mix({//缓动公式
easing: {
linear: function(pos) {
return pos;
@@ -22,22 +22,22 @@ define("fx", ["css"], function($) {
//用于向主列队或元素的子列队插入动画实例,并会让停走了的定时器再次动起来
function tick(fx) {
- if(fx.queue) { //让同一个元素的动画一个接一个执行
- var gotoQueue = true;
- for(var i = timeline.length, el; el = timeline[--i];) {
- if(el.node == fx.node) { //★★★第一步
+ if (fx.queue) { //让同一个元素的动画一个接一个执行
+ var gotoQueue = 1;
+ for (var i = timeline.length, el; el = timeline[--i]; ) {
+ if (el.node === fx.node) { //★★★第一步
el.positive.push(fx); //子列队
- gotoQueue = false
+ gotoQueue = 0;
break;
}
}
- if(gotoQueue) { //★★★第二步
+ if (gotoQueue) { //★★★第二步
timeline.unshift(fx);
}
} else {
- timeline.push(fx)
+ timeline.push(fx);
}
- if(tick.id === null) {
+ if (tick.id === null) {
tick.id = setInterval(nextTick, 1000 / $.fps); //原始的setInterval id并执行动画
}
}
@@ -47,62 +47,62 @@ define("fx", ["css"], function($) {
function nextTick() {
//用于从主列队中剔除已经完成或被强制完成的动画实例,一旦主列队被清空,还负责中止定时器,节省内存
var i = timeline.length;
- while(--i >= 0) {
- if(!(timeline[i].node && animate(timeline[i], i))) {
+ while (--i >= 0) {
+ if (!(timeline[i].node && animate(timeline[i], i))) {
timeline.splice(i, 1);
}
}
timeline.length || (clearInterval(tick.id), tick.id = null);
}
- var effect = $.fn.fx = function(props, /*internal*/ p) {
- var opts = resetArguments.apply(null, arguments);
- if((props = opts.props)) {
- var ease = opts.specialEasing;
- for(var name in props) {
- p = $.cssName(name) || name;
- if(name != p) {
- props[p] = props[name]; //收集用于渐变的属性
- ease[p] = ease[name];
- delete ease[name];
- delete props[name];
- }
+ var effect = $.fn.fx = function(props, /*internal*/p) {
+ var opts = resetArguments.apply(null, arguments);
+ if ((props = opts.props)) {
+ var ease = opts.specialEasing;
+ for (var name in props) {
+ p = $.cssName(name) || name;
+ if (name !== p) {
+ props[p] = props[name]; //收集用于渐变的属性
+ ease[p] = ease[name];
+ delete ease[name];
+ delete props[name];
}
}
- for(var i = 0, node; node = this[i++];) {
- tick($.mix({
- positive: [],
- negative: [],
- method: "noop",
- node: node
- }, opts, false));
- }
- return this;
}
+ for (var i = 0, node; node = this[i++]; ) {
+ tick($.mix({
+ positive: [],
+ negative: [],
+ method: "noop",
+ node: node
+ }, opts, false));
+ }
+ return this;
+ }
$.fn.animate = effect;
function addOptions(opts, p) {
//.animate( properties [, duration] [, easing] [, complete] )
//.animate( properties, options )
- switch($.type(p)) {
- case "Object":
- delete p.props;
- $.mix(opts, p);
- break;
- case "Number":
- opts.duration = p;
- break;
- case "String":
- opts.easing = p;
- break;
- case "Function":
- opts.complete = p;
- break;
+ switch ($.type(p)) {
+ case "Object":
+ delete p.props;
+ $.mix(opts, p);
+ break;
+ case "Number":
+ opts.duration = p;
+ break;
+ case "String":
+ opts.easing = p;
+ break;
+ case "Function":
+ opts.complete = p;
+ break;
}
}
function resetArguments(properties) {
- if(isFinite(properties)) {
+ if (isFinite(properties)) {
return {
duration: properties
}
@@ -111,14 +111,15 @@ define("fx", ["css"], function($) {
props: properties
}
//如果第二参数是对象
- for(var i = 1; i < arguments.length; i++) {
+ for (var i = 1; i < arguments.length; i++) {
addOptions(opts, arguments[i]);
}
opts.duration = typeof opts.duration === "number" ? opts.duration : 400;
- opts.queue = !! (opts.queue == null || opts.queue); //默认使用列队
+ opts.queue = !!(opts.queue == null || opts.queue); //默认使用列队
opts.specialEasing = opts.specialEasing || {};
return opts;
- };
+ }
+ ;
effect.updateHooks = {
_default: function(node, per, end, obj) {
@@ -126,9 +127,9 @@ define("fx", ["css"], function($) {
},
color: function(node, per, end, obj) {
var pos = obj.easing(per),
- rgb = end ? obj.to : obj.from.map(function(from, i) {
- return Math.min(from + (obj.to[i] - from) * pos % 256, 0);
- });
+ rgb = end ? obj.to : obj.from.map(function(from, i) {
+ return Math.min(from + (obj.to[i] - from) * pos % 256, 0);
+ });
node.style[obj.name] = "rgb(" + rgb + ")";
}
}
@@ -138,14 +139,14 @@ define("fx", ["css"], function($) {
}
}
effect._default = $.css, //getter
- effect.scroll = function(el, prop) { //getter
+ effect.scroll = function(el, prop) { //getter
return el[prop];
}
var Animation = {
fx: function(nodes, properties, args) {
//由于构建更高级的基于元素节点的复合动画
var options = {}
- for(var i = 1; i < args.length; i++) {
+ for (var i = 1; i < args.length; i++) {
addOptions(options, args[i]);
}
"before,after".replace($.rword, function(call) {
@@ -154,10 +155,11 @@ define("fx", ["css"], function($) {
});
return nodes.fx(properties, options);
},
- noop: function() {},
+ noop: function() {
+ },
type: function(attr) { // 用于取得适配器的类型
- for(var i in types) {
- if(types[i].test(attr)) {
+ for (var i in types) {
+ if (types[i].test(attr)) {
return i;
}
}
@@ -167,20 +169,20 @@ define("fx", ["css"], function($) {
//show 开始时计算其width1 height1 保存原来的width height display改为inline-block或block overflow处理 赋值(width1,height1)
//hide 保存原来的width height 赋值为(0,0) overflow处理 结束时display改为none;
//toggle 开始时判定其是否隐藏,使用再决定使用何种策略
- if(node.nodeType == 1 && $.isHidden(node)) {
+ if (node.nodeType == 1 && $.isHidden(node)) {
var display = $._data(node, "olddisplay");
- if(!display || display == "none") {
+ if (!display || display == "none") {
display = $.parseDisplay(node.nodeName)
$._data(node, "olddisplay", display);
}
node.style.display = display;
- if("width" in fx.props || "height" in fx.props) { //如果是缩放操作
+ if ("width" in fx.props || "height" in fx.props) { //如果是缩放操作
//修正内联元素的display为inline-block,以让其可以进行width/height的动画渐变
- if(display === "inline" && $.css(node, "float") === "none") {
- if(!$.support.inlineBlockNeedsLayout) { //w3c
+ if (display === "inline" && $.css(node, "float") === "none") {
+ if (!$.support.inlineBlockNeedsLayout) { //w3c
node.style.display = "inline-block";
} else { //IE
- if(display === "inline") {
+ if (display === "inline") {
node.style.display = "inline-block";
} else {
node.style.display = "inline";
@@ -192,20 +194,20 @@ define("fx", ["css"], function($) {
}
},
hide: function(node, fx) {
- if(node.nodeType == 1 && !$.isHidden(node)) {
+ if (node.nodeType == 1 && !$.isHidden(node)) {
var display = $.css(node, "display"),
- s = node.style;
- if(display !== "none" && !$._data(node, "olddisplay")) {
+ s = node.style;
+ if (display !== "none" && !$._data(node, "olddisplay")) {
$._data(node, "olddisplay", display);
}
- if("width" in fx.props || "height" in fx.props) { //如果是缩放操作
+ if ("width" in fx.props || "height" in fx.props) { //如果是缩放操作
//确保内容不会溢出,记录原来的overflow属性,因为IE在改变overflowX与overflowY时,overflow不会发生改变
fx.overflow = [s.overflow, s.overflowX, s.overflowY];
s.overflow = "hidden";
}
fx.after = function(node, fx) {
s.display = "none";
- if(fx.overflow != null) {
+ if (fx.overflow != null) {
["", "X", "Y"].forEach(function(postfix, index) {
s["overflow" + postfix] = fx.overflow[index]
});
@@ -219,46 +221,46 @@ define("fx", ["css"], function($) {
create: function(node, fx, index) {
//用于生成动画实例的关键帧(第一帧与最后一帧)所需要的计算数值与单位,并将回放用的动画放到negative子列队中去
var to, parts, unit, op, parser, props = [],
- revertProps = [],
- orig = {},
- hidden = $.isHidden(node),
- ease = fx.specialEasing,
- hash = fx.props,
- easing = fx.easing //公共缓动公式
- if(!hash.length) {
- for(var name in hash) {
- if(!hash.hasOwnProperty(name)) {
+ revertProps = [],
+ orig = {},
+ hidden = $.isHidden(node),
+ ease = fx.specialEasing,
+ hash = fx.props,
+ easing = fx.easing //公共缓动公式
+ if (!hash.length) {
+ for (var name in hash) {
+ if (!hash.hasOwnProperty(name)) {
continue
}
var val = hash[name] //取得结束值
var type = Animation.type(name); //取得类型
var from = (effect[type] || effect._default)(node, name); //取得起始值
//用于分解属性包中的样式或属性,变成可以计算的因子
- if(val === "show" || (val === "toggle" && hidden)) {
+ if (val === "show" || (val === "toggle" && hidden)) {
val = $._data(node, "old" + name) || from;
fx.method = "show";
from = 0;
$.css(node, name, 0);
- } else if(val === "hide" || val === "toggle") { //hide
+ } else if (val === "hide" || val === "toggle") { //hide
orig[name] = $._data(node, "old" + name, from);
fx.method = "hide";
val = 0;
}
- if((parser = effect.parseHooks[type])) {
+ if ((parser = effect.parseHooks[type])) {
parts = parser(node, from, val);
} else {
from = !from || from == "auto" ? 0 : parseFloat(from) //确保from为数字
- if((parts = rfxnum.exec(val))) {
+ if ((parts = rfxnum.exec(val))) {
to = parseFloat(parts[2]), //确保to为数字
- unit = $.cssNumber[name] ? 0 : (parts[3] || "px");
- if(parts[1]) {
+ unit = $.cssNumber[name] ? 0 : (parts[3] || "px");
+ if (parts[1]) {
op = parts[1].charAt(0); //操作符
- if(unit && unit !== "px" && (op == "+" || op == "-")) {
+ if (unit && unit !== "px" && (op == "+" || op == "-")) {
$.css(node, name, (to || 1) + unit);
from = ((to || 1) / parseFloat($.css(node, name))) * from;
$.css(node, name, from + unit);
}
- if(op) { //处理+=,-= \= *=
+ if (op) { //处理+=,-= \= *=
to = eval(from + op + to);
}
}
@@ -269,7 +271,7 @@ define("fx", ["css"], function($) {
}
from = parts[0];
to = parts[1];
- if(from + "" === to + "") { //不处理初止值都一样的样式与属性
+ if (from + "" === to + "") { //不处理初止值都一样的样式与属性
continue
}
var prop = {
@@ -290,9 +292,9 @@ define("fx", ["css"], function($) {
fx.revertProps = revertProps;
fx.orig = orig;
}
- if(fx.record || fx.revert) {
+ if (fx.record || fx.revert) {
var fx2 = {}; //回滚到最初状态
- for(name in fx) {
+ for (name in fx) {
fx2[name] = fx[name];
}
fx2.record = fx2.revert = void 0
@@ -306,7 +308,7 @@ define("fx", ["css"], function($) {
function callback(fx, node, name) {
- if(fx[name]) {
+ if (fx[name]) {
fx[name].call(node, node, fx);
}
}
@@ -315,8 +317,8 @@ define("fx", ["css"], function($) {
//驱动主列队的动画实例进行补间动画(update),执行各种回调(before, step, after, complete),
//并在动画结束后,从子列队选取下一个动画实例取替自身
var node = fx.node,
- now = +new Date;
- if(!fx.startTime) { //第一帧
+ now = +new Date;
+ if (!fx.startTime) { //第一帧
callback(fx, node, "before"); //动画开始前的预操作
fx.props && Animation.create(fx.node, fx, index); //添加props属性与设置负向列队
fx.props = fx.props || [];
@@ -327,23 +329,23 @@ define("fx", ["css"], function($) {
var end = fx.gotoEnd || per >= 1;
var hooks = effect.updateHooks
// 处理渐变
- for(var i = 0, obj; obj = fx.props[i++];) {
+ for (var i = 0, obj; obj = fx.props[i++]; ) {
(hooks[obj.type] || hooks._default)(node, per, end, obj);
}
- if(end) { //最后一帧
- if(fx.method === "hide") {
- for(var i in fx.orig) { //还原为初始状态
+ if (end) { //最后一帧
+ if (fx.method === "hide") {
+ for (var i in fx.orig) { //还原为初始状态
$.css(node, i, fx.orig[i]);
}
}
callback(fx, node, "after"); //动画结束后执行的一些收尾工作
callback(fx, node, "complete"); //执行用户回调
- if(fx.revert && fx.negative.length) {
+ if (fx.revert && fx.negative.length) {
Array.prototype.unshift.apply(fx.positive, fx.negative.reverse());
fx.negative = []; // 清空负向列队
}
var neo = fx.positive.shift();
- if(!neo) {
+ if (!neo) {
return false;
}
timeline[index] = neo;
@@ -365,31 +367,31 @@ define("fx", ["css"], function($) {
gotoEnd = gotoEnd ? "1" : "0";
var stopCode = parseInt(clearQueue + gotoEnd, 2); //返回0 1 2 3
return this.each(function(node) {
- for(var i = 0, fx; fx = timeline[i]; i++) {
- if(fx.node === node) {
- switch(stopCode) { //如果此时调用了stop方法
- case 0:
- //中断当前动画,继续下一个动画
- fx.update = fx.step = $.noop
- fx.revert && fx.negative.shift();
- fx.gotoEnd = true;
- break;
- case 1:
- //立即跳到最后一帧,继续下一个动画
- fx.gotoEnd = true;
- break;
- case 2:
- //清空该元素的所有动画
- delete fx.node
- break;
- case 3:
- Array.prototype.unshift.apply(fx.positive, fx.negative.reverse());
- fx.negative = []; // 清空负向列队
- for(var j = 0; fx = fx.positive[j++];) {
- fx.before = fx.after = fx.step = $.noop
- fx.gotoEnd = true; //立即完成该元素的所有动画
- }
- break;
+ for (var i = 0, fx; fx = timeline[i]; i++) {
+ if (fx.node === node) {
+ switch (stopCode) { //如果此时调用了stop方法
+ case 0:
+ //中断当前动画,继续下一个动画
+ fx.update = fx.step = $.noop
+ fx.revert && fx.negative.shift();
+ fx.gotoEnd = true;
+ break;
+ case 1:
+ //立即跳到最后一帧,继续下一个动画
+ fx.gotoEnd = true;
+ break;
+ case 2:
+ //清空该元素的所有动画
+ delete fx.node
+ break;
+ case 3:
+ Array.prototype.unshift.apply(fx.positive, fx.negative.reverse());
+ fx.negative = []; // 清空负向列队
+ for (var j = 0; fx = fx.positive[j++]; ) {
+ fx.before = fx.after = fx.step = $.noop
+ fx.gotoEnd = true; //立即完成该元素的所有动画
+ }
+ break;
}
}
}
@@ -406,7 +408,7 @@ define("fx", ["css"], function($) {
var obj = {};
fxAttrs.concat.apply([], fxAttrs.slice(0, num)).forEach(function(name) {
obj[name] = type;
- if(~name.indexOf("margin")) {
+ if (~name.indexOf("margin")) {
effect.updateHooks[name] = function(node, per, end, obj) {
var val = (end ? obj.to : obj.from + (obj.from - obj.to) * obj.easing(per));
node.style[name] = Math.max(val, 0) + obj.unit;
@@ -440,7 +442,7 @@ define("fx", ["css"], function($) {
["toggle", "show", "hide"].forEach(function(name, i) {
var pre = $.fn[name];
$.fn[name] = function(a) {
- if(!arguments.length || typeof a == "boolean") {
+ if (!arguments.length || typeof a == "boolean") {
return pre.apply(this, arguments)
} else {
return Animation.fx(this, genFx(name, 3), arguments);
@@ -450,10 +452,10 @@ define("fx", ["css"], function($) {
function beforePuff(node, fx) {
var position = $.css(node, "position"),
- width = $.css(node, "width"),
- height = $.css(node, "height"),
- left = $.css(node, "left"),
- top = $.css(node, "top");
+ width = $.css(node, "width"),
+ height = $.css(node, "height"),
+ left = $.css(node, "left"),
+ top = $.css(node, "top");
node.style.position = "relative";
$.mix(fx.props, {
width: "*=1.5",
@@ -475,7 +477,8 @@ define("fx", ["css"], function($) {
return Animation.fx(this, {
before: beforePuff
}, arguments);
- }
+ };
+ //=======================转换各种颜色值为RGB数组===========================
var colorMap = {
"black": [0, 0, 0],
"gray": [128, 128, 128],
@@ -499,36 +502,38 @@ define("fx", ["css"], function($) {
function color2array(val) { //将字符串变成数组
var color = val.toLowerCase(),
- ret = [];
- if(colorMap[color]) {
+ ret = [];
+ if (colorMap[color]) {
return colorMap[color];
}
- if(color.indexOf("rgb") === 0) {
+ if (color.indexOf("rgb") === 0) {
var match = color.match(/(\d+%?)/g),
- factor = match[0].indexOf("%") !== -1 ? 2.55 : 1;
+ factor = match[0].indexOf("%") !== -1 ? 2.55 : 1;
return(colorMap[color] = [parseInt(match[0]) * factor, parseInt(match[1]) * factor, parseInt(match[2]) * factor]);
- } else if(color.charAt(0) === '#') {
- if(color.length === 4) color = color.replace(/([^#])/g, '$1$1');
+ } else if (color.charAt(0) === '#') {
+ if (color.length === 4)
+ color = color.replace(/([^#])/g, '$1$1');
color.replace(/\w{2}/g, function(a) {
- ret.push(parseInt(a, 16))
+ ret.push(parseInt(a, 16));
});
return(colorMap[color] = ret);
}
- if(window.VBArray) {
+ if (window.VBArray) {
return(colorMap[color] = parseColor(color));
}
return colorMap.white;
}
- $.parseColor = color2array
- if($.query && $.query.pseudoHooks) {
+ $.parseColor = color2array;
+ //为选择器引擎添加:animated伪类
+ try {
$.query.pseudoHooks.animated = function(el) {
- for(var i = 0, fx; fx = timeline[i++];) {
- if(el === fx.node) {
+ for (var i = 0, fx; fx = timeline[i++]; ) {
+ if (el === fx.node) {
return true;
}
}
- }
- }
+ };
+ } catch (e) { }
return $;
})
/**
Please sign in to comment.
Something went wrong with that request. Please try again.