• MooTools 1.4 源码分析 Fx.CSS


    本文参考了我佛山人的Mootools1.2的源码分析二十九 -- Fx.CSS

    View Code
      1     /*
    2 ---
    3
    4 name: Fx.CSS
    5
    6 description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.
    7
    8 license: MIT-style license.
    9
    10 requires: [Fx, Element.Style]
    11
    12 provides: Fx.CSS
    13
    14 源码分析: 苦苦的苦瓜(http://www.cnblogs.com/hmking)
    15
    16 ...
    17 */
    18
    19 /**
    20 * @Fx.CSS: 跟CSS有关的动画的基类,这里的动画,主要是从一个开始值到结束值的变化效果
    21 **/
    22 Fx.CSS = new Class({
    23
    24 // 继承自Fx
    25 Extends: Fx,
    26
    27 // prepares the base from/to object
    28 /**
    29 * @method: prepare
    30 * @param element - (object) 特效作用的元素对象
    31 * @param property - (string) CSS属性
    32 * @param values - (mixed) 包含开始值和结束值的数组或一个单值(结束值)
    33 * @returns: (object) - 包含from和to两个键值的对象字面量
    34 * @description: 动画的开始和结束值的前期处理
    35 * @notes: 此时from和to两个键的值为数组类型
    36 **/
    37 prepare: function (element, property, values) {
    38 // 把变量values数组化,因为values可能传一个单值,也可能是一个数组
    39 values = Array.from(values);
    40 // 取特效的起始值和结束值,如果如果只传了一个值,则本值将作为结束值,CSS属性的当前值为特效起始值
    41 if (values[1] == null) {
    42 values[1] = values[0];
    43 values[0] = element.getStyle(property);
    44 }
    45 // 将数组中的项使用parse方法解释
    46 var parsed = values.map(this.parse);
    47 // 返回from和to两个键值的对象字面量
    48 return { from: parsed[0], to: parsed[1] };
    49 },
    50
    51 //parses a value into an array
    52 /**
    53 * @method: parse
    54 * @param value - (mixed) CSS属性值
    55 * @returns: (array) - 数组项值为包含value和parser两个键值的对象字面量,存储解释过的CSS属性值和包含针对此属性值的解释器
    56 * @description: 解析一个CSS属性值为一个数组
    57 **/
    58 parse: function (value) {
    59 // 使用lambad表达式,将value函数化之后再执行,这样的好处是使传的值可以是function,也可以是固定值
    60 value = Function.from(value)();
    61 // 数组化,如果是字符串类型,使用空格分隔成数组
    62 value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
    63 // 对数组逐项处理
    64 return value.map(function (val) {
    65 // 转为字符类型
    66 val = String(val);
    67 var found = false;
    68 Object.each(Fx.CSS.Parsers, function (parser, key) {
    69 // 第一项时这里为false继续执行下面,找到合适的解释器后found判断不再为false,避免重复解释
    70 if (found) { return; }
    71 // 尝试使用解释器解释值
    72 var parsed = parser.parse(val);
    73 // 如果解释成功,记录解释后的值和使用的解释器(因为还要使用解释器的compute和serve方法)
    74 if (parsed || parsed === 0) {
    75 found = {
    76 value: parsed,
    77 parser: parser
    78 };
    79 }
    80 });
    81 // 默认使用字符串值的解释器
    82 found = found || {
    83 value: val,
    84 parser: Fx.CSS.Parsers.String
    85 };
    86 return found;
    87 });
    88 },
    89
    90 // computes by a from and to prepared objects, using their parsers.
    91 /**
    92 * @method: compute
    93 * @param from - (array) 解释过的CSS属性的起始值的数组
    94 * @param to - (array) 解释过的CSS属性的结束值的数组
    95 * @param delta - (mixed) 特效变化所需要的比例因子
    96 * @returns: (array) 包含计算过的特效当前CSS属性值信息的一个数组
    97 * @description: 根据初始值,结束值和比例因子求目标值
    98 **/
    99 compute: function (from, to, delta) {
    100 var computed = [];
    101 // 取数项小的遍历
    102 (Math.min(from.length, to.length)).times(function (i) {
    103 // 返回计算过的值和使用的解释器
    104 computed.push({
    105 value: from[i].parser.compute(from[i].value, to[i].value, delta),
    106 parser: from[i].parser
    107 });
    108 });
    109 // 为typeOf提供精准类型值
    110 computed.$family = Function.from('fx:css:value');
    111 return computed;
    112 },
    113
    114 // serves the value as settable
    115 /**
    116 * @method: serve
    117 * @param value - (mixed) CSS属性目标值,此参数可以是一个解释过的CSS属性值数组,也可以为一个CSS属性值
    118 * @param unit - (string 默认为 false) 计量单位(如: 'px', 'em', 或 '%').
    119 * @returns: (array) 包含计算过的特效当前CSS属性值信息的一个数组
    120 * @description: 对计算过的CSS属性值数组对象做最后的包装处理,使其可应用于Element.setStyle方法
    121 **/
    122 serve: function (value, unit) {
    123 // 如果值未经解释,需要先解释(比如单独调用set方法)
    124 if (typeOf(value) != 'fx:css:value') {
    125 value = this.parse(value);
    126 }
    127 var returned = [];
    128 value.each(function (bit) {
    129 // 得到最终的使用值
    130 returned = returned.concat(bit.parser.serve(bit.value, unit));
    131 });
    132 return returned;
    133 },
    134
    135 // renders the change to an element
    136 // 因为类本身是跟CSS有类,所以最终将计算出的数组通过setStyle反映到element的相应CSS属性上
    137 render: function (element, property, value, unit) {
    138 element.setStyle(property, this.serve(value, unit));
    139 },
    140
    141 // searches inside the page css to find the values for a selector
    142 // 从当前页面的样式中查找指定选择符的样式设置
    143 search: function (selector) {
    144 // 模拟缓存,先从临时对象中找相应键值,提高效率
    145 if (Fx.CSS.Cache[selector]) { return Fx.CSS.Cache[selector]; }
    146 var to = {},
    147 selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');
    148 // 遍历当前页面的样式表
    149 Array.each(document.styleSheets, function (sheet, j) {
    150 var href = sheet.href;
    151 // 忽略跨域的外链样式表
    152 if (href && href.contains('://') && !href.contains(document.domain)) {
    153 return;
    154 }
    155 // 样式规则集
    156 var rules = sheet.rules || sheet.cssRules;
    157 // 遍历每条规则
    158 Array.each(rules, function (rule, i) {
    159 if (!rule.style) { return; }
    160 // 选择符(类型选择符的话会转为小写)
    161 var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function (m) {
    162 return m.toLowerCase();
    163 }) : null;
    164 // 匹配指定的样式选择符
    165 if (!selectorText || !selectorTest.test(selectorText)) { return; }
    166 // 样式值分析
    167 Object.each(Element.Styles, function (value, style) {
    168 // 无值
    169 if (!rule.style[style] || Element.ShortStyles[style]) { return; }
    170 // 转为字符串
    171 value = String(rule.style[style]);
    172 // 颜色值处理
    173 to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;
    174 });
    175 });
    176 });
    177 // 缓存
    178 return Fx.CSS.Cache[selector] = to;
    179 }
    180
    181 });
    182
    183 Fx.CSS.Cache = {};
    184
    185 // #region - 解释器 -
    186
    187 // CSS中几种值类型的解释器,每个解释器必须实现parse/compute/serve三个接口
    188 Fx.CSS.Parsers = {
    189
    190 // 对颜色的解释处理
    191 Color: {
    192
    193 parse: function (value) {
    194 // 如果是十六进制的颜色表示,处理成RGB数组
    195 if (value.match(/^#[0-9a-f]{3,6}$/i)) {
    196 return value.hexToRgb(true);
    197 }
    198 // 如果是RGB的颜色显示,正则匹配出RGB数组,不匹配返回flase,以便引擎调用其它解释器解释
    199 return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
    200 },
    201
    202 compute: function (from, to, delta) {
    203 // 对R、G和B分别计算目标值
    204 return from.map(function (value, i) {
    205 // 可以看到仍然使用静态的compute方法
    206 return Math.round(Fx.compute(from[i], to[i], delta));
    207 });
    208 },
    209
    210 serve: function (value) {
    211 // 将R、G、B都转成数值型
    212 return value.map(Number);
    213 }
    214
    215 },
    216
    217 // 数值类型的解释处理
    218 Number: {
    219
    220 // 转为浮点数
    221 parse: parseFloat,
    222
    223 // 跟Fx中的算法一样
    224 compute: Fx.compute,
    225
    226 serve: function (value, unit) {
    227 // 加上单位,比如px,pt之类
    228 return (unit) ? value + unit : value;
    229 }
    230
    231 },
    232
    233 // 对字符类型的解释处理
    234 String: {
    235
    236 // 解释器返回false,相当于parse : function(){return false;}
    237 parse: Function.from(false),
    238
    239 // compute方法执行时返回第2个参数
    240 compute: function (zero, one) {
    241 return one;
    242 },
    243
    244 // serve方法执行时返回第1个参数
    245 serve: function (zero) {
    246 return zero;
    247 }
    248
    249 }
    250
    251 };
    252
    253 // #endregion

  • 相关阅读:
    多角度分析平台即服务?PaaS的类型和用例
    2021.3.10 Android导出Excel表
    2021.3.9 个人作业阶段2
    2021.3.8 Android图像视图1
    2021.3.7 Android图像视图
    2021.3.6 Android页面刷新
    2021.3.5 个人作业1+家庭记账本(8)
    2021.3.4 家庭记账本(7)
    2021.3.3 Android项目打包+家庭记账本(6)
    2021.3.2 开课博客+家庭记账本(5)
  • 原文地址:https://www.cnblogs.com/hmking/p/2196606.html
Copyright © 2020-2023  润新知