MooTools 1.4 源码分析 - Fx.Tween
Mootools1.4 - Fx.Tween类的源码分析,如果理解有误欢迎指正:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*
2 ---
3
4 name: Fx.Tween
5
6 description: Formerly Fx.Style, effect to transition any CSS property for an element.
7
8 license: MIT-style license.
9
10 requires: Fx.CSS
11
12 provides: [Fx.Tween, Element.fade, Element.highlight]
13
14 源码分析: 苦苦的苦瓜(http://www.cnblogs.com/hmking)
15
16 ...
17 */
18
19 // #region - Fx.Tween -
20
21 /**
22 * @Fx.Tween: 对元素单个样式属性执行一个特效
23 **/
24 Fx.Tween = new Class({
25
26 // 继承自Fx.CSS
27 Extends: Fx.CSS,
28
29 /**
30 * @method: initialize
31 * @param element - (mixed) 元素的id或引用
32 * @param options - (object, 可选) 类可用的所有可选项, 以及如下的可选项:
33 * property - (string, 默认为null) 变换的目标CSS属性,例如:'width', 'color', 'font-size', 'border'等.
34 * 如果在此省略该可选项, 则在执行start或set方法时,需要在方法的第一个参数上指定一个CSS属性.
35 * @description: 构造函数,提供将元素的一个CSS属性值从一个值向另一个值进行转化的功能
36 * @notes:
37 * 任何可以用Element:setStyle设置的CSS属性都可以用于Fx.Tween
38 * 如果不是可计算型的CSS属性, 如border-style 或 background-image等, 则只是简单的设置它的值
39 * 如果使用了property可选项, 则在调用start和set方法时就不用再指定CSS属性
40 **/
41 initialize: function (element, options) {
42 // element属性存储特效所作用的元素对象
43 this.element = this.subject = document.id(element);
44 // 调用父类的同名方法
45 this.parent(options);
46 },
47
48 /**
49 * @method: set
50 * @param property - (string) css属性(如果在构造函数中设置了property可选项, 则该处可以省略)
51 * @param now - (mixed) css属性值
52 * @description: 将元素的指定CSS属性值立即设置为指定的值
53 * @returns: (object) 主调Fx.Tween实例
54 * @notes:
55 * 如果使用了property可选项, 或者在start方法中指定了CSS属性参数,则在调用set方法时就不用指定CSS属性参数
56 **/
57 set: function (property, now) {
58 // 如果只提供一个参数
59 if (arguments.length == 1) {
60 // 将此参数作为目标值
61 now = property;
62 // 取CSS属性,首先取Fx实例的property属性存储的CSS属性名
63 property = this.property || this.options.property;
64 }
65 // 最终渲染效果
66 this.render(this.element, property, now, this.options.unit);
67 return this;
68 },
69
70 /**
71 * @method: start
72 * @param property - (string) 要进行变换的css属性(如果在构造函数中设置了property可选项, 则该处可以省略)
73 * @param from - (mixed) CSS属性起始值。如果整个方法只给出一个参数,则该值作为CSS属性的结束值
74 * @param to - (mixed, 可选) CSS属性结束值
75 * @description: 将元素的CSS属性值过度到指定值
76 * @notes:
77 * 如果整个方法只给出一个参数,则该值作为CSS属性的结束值, 起始值则从元素的当前状态计算而来
78 * 当变换颜色类的CSS属性时, 既可使用RGB格式也可以使用十六进制格式
79 * 如果在构造函数中设置了property可选项, 则在调用start方法时就不用指定CSS属性参数
80 **/
81 start: function (property, from, to) {
82 // 检查当前特效运行状态,决定是否运行新特效
83 if (!this.check(property, from, to)) { return this; }
84 // 将参数降维
85 var args = Array.flatten(arguments);
86 // 取CSS属性,首先判断有没有设置property可选项
87 this.property = this.options.property || args.shift();
88 // 调用父类Fx.CSS的prepare方法解释参数,得到from和to值
89 var parsed = this.prepare(this.element, this.property, args);
90 // 调用Fx基类的同名方法,开始执行特效
91 return this.parent(parsed.from, parsed.to);
92 }
93
94 });
95
96 // #endregion
97
98 // #region - Element.Properties.tween -
99
100 /**
101 * @element property: tween
102 * @description: 用于设置或获取元素上的Fx.Tween实例,实现单件模式
103 * @notes:
104 * 01、When initializing the Element's tween instance with Element:set, the property to tween SHOULD NOT be passed.
105 * 当使用Element:set方法来设置元素的tween时, 则要进行tween的css属性<不需要>传入
106 * 02、The property must be specified when using Element:get to retrieve the actual Fx.Tween instance, and in calls to Element:tween
107 * 当使用Element:get方法来获取元素的Fx.Tween实例时, 则可选项中的property必须指定
108 * 03、When options are passed to the setter, the instance will be reset.
109 * 当使用setter方法设置可选参数时,Fx.Tween实例对象会被重置
110 * 04、As with the other Element shortcuts, the difference between a setter and a getter is that the getter returns the instance, while the setter returns the element (for chaining and initialization).
111 * 调用get方法获取tween返回的是Fx.Tween的实例, 而调用set返回的是主调元素
112 * 05、当使用get方法时, 如果元素上还不存在tween, 则会根据给出的可选项新建一个实例设置到元素上
113 **/
114 Element.Properties.tween = {
115
116 // setter设置Fx.Tween对象参数
117 set: function (options) {
118 // 取得Fx.Tween实例,取消执行中的特效,然后再设置可选参数
119 this.get('tween').cancel().setOptions(options);
120 return this;
121 },
122
123 get: function () {
124 // 先从临时对象读取,看有没缓存到Fx.Tween实例
125 var tween = this.retrieve('tween');
126 if (!tween) {
127 // 保存Fx.Tween实例
128 tween = new Fx.Tween(this, { link: 'cancel' });
129 this.store('tween', tween);
130 }
131 return tween;
132 }
133
134 };
135
136 // #endregion
137
138 // #region - Element Methods -
139
140 // 元素进行特效变换的快捷方法
141 Element.implement({
142
143 /**
144 * @element method: tween
145 * @returns: (element) 返回主调元素
146 * @notes: 参照Fx.Tween.start方法
147 **/
148 tween: function (property, from, to) {
149 this.get('tween').start(property, from, to);
150 return this;
151 },
152
153 /**
154 * @element method: fade
155 * @param how - (mixed, 可选: 默认为'toggle') 代表不透明度的数值或字符串. 可为如下值:
156 * 'in' - opacity为100%
157 * 'out' - opacity为0%
158 * 'show' - opacity立即设置为100%
159 * 'hide' - opacity立即设置为0%
160 * 'toggle' - 如果元素当前为可见状态, 则将元素淡出; 相反, 则将元素淡入
161 * (number) - 0~1之间的浮点数. 将代入淡出到该值.
162 * @returns: (element) 返回主调元素
163 * @description: 对opacity样式属性进行tween特效变换的快捷方法,实现的深入浅出效果
164 **/
165 fade: function (how) {
166 // 取得主调元素的Fx.Tween实例
167 var fade = this.get('tween'),
168 method, to, toggle;
169 if (how == null) { how = 'toggle'; }
170 // 几种淡入淡出的方式
171 switch (how) {
172 case 'in': // 淡入
173 method = 'start';
174 to = 1;
175 break;
176
177 case 'out': // 淡出
178 method = 'start';
179 to = 0;
180 break;
181
182 case 'show': // 显示
183 method = 'set';
184 to = 1;
185 break;
186
187 case 'hide': // 隐藏
188 method = 'set';
189 to = 0;
190 break;
191
192 case 'toggle': // 开关
193 // 获取标记变量, 第二个参数用于默认值
194 var flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1);
195 method = 'start';
196 // 根据标记状态控制淡入还是淡出
197 to = flag ? 0 : 1;
198 // 将标记取反保存
199 this.store('fade:flag', !flag);
200 toggle = true;
201 break;
202
203 default:
204 method = 'start';
205 to = how;
206 }
207 // 如果没有使用开关方式,删除临时标记,避免在使用toggle之后又使用其它方式,导致toggle响应错误
208 if (!toggle) { this.eliminate('fade:flag'); }
209 // 根据指定的淡入淡出方式执行特效实例相应的方法
210 fade[method]('opacity', to);
211 // 根据opacity样式属性结束值是否为零来设置主调元素隐藏还是显示
212 if (method == 'set' || to != 0) {
213 this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');
214 } else fade.chain(function () {
215 this.element.setStyle('visibility', 'hidden');
216 });
217 return this;
218 },
219
220 /**
221 * @element method: highlight
222 * @param start - (string, 可选: 默认为'#ff8') 高亮色
223 * @param end - (string, 可选: 默认为元素初始的background-color值) 高亮效果结束后的元素背景颜色
224 * @returns: (element) 返回主调元素
225 * @description: 对background-color样式属性进行tween特效变换的快捷方法.(即背景高亮特效, 将背景颜色迅速设置为指定颜色,随后返回到初始的背景颜色)
226 * @notes: 如果未给元素指定背景色, 或指定成了'transparent', 则end值默认为白色
227 **/
228 highlight: function (start, end) {
229 // end为动画结束后使用的背景色,通常是原来恢复原来的颜色
230 if (!end) {
231 // 临时对象取值
232 end = this.retrieve('highlight:original', this.getStyle('background-color'));
233 // 透明的话按白色处理
234 end = (end == 'transparent') ? '#fff' : end;
235 }
236 // 获取主调元素的Fx.Tween实例
237 var tween = this.get('tween');
238 // 开始执行
239 tween.start('background-color', start || '#ffff88', end).chain(function () {
240 // 动画结束恢复原来颜色
241 this.setStyle('background-color', this.retrieve('highlight:original'));
242 // 链式执行
243 tween.callChain();
244 } .bind(this));
245 return this;
246 }
247
248 });
249
250 // #endregion