1 /**
  2  * @fileOverview special patch for making color gradual change
  3  * @author  yiminghe@gmail.com
  4  */
  5 KISSY.add("anim/color", function (S, DOM, Anim, Fx) {
  6 
  7     var HEX_BASE = 16,
  8 
  9         floor = Math.floor,
 10 
 11         KEYWORDS = {
 12             black:[0, 0, 0],
 13             silver:[192, 192, 192],
 14             gray:[128, 128, 128],
 15             white:[255, 255, 255],
 16             maroon:[128, 0, 0],
 17             red:[255, 0, 0],
 18             purple:[128, 0, 128],
 19             fuchsia:[255, 0, 255],
 20             green:[0, 128, 0],
 21             lime:[0, 255, 0],
 22             olive:[128, 128, 0],
 23             yellow:[255, 255, 0],
 24             navy:[0, 0, 128],
 25             blue:[0, 0, 255],
 26             teal:[0, 128, 128],
 27             aqua:[0, 255, 255]
 28         },
 29         re_RGB = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
 30 
 31         re_RGBA = /^rgba\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+),\s*([0-9]+)\)$/i,
 32 
 33         re_hex = /^#?([0-9A-F]{1,2})([0-9A-F]{1,2})([0-9A-F]{1,2})$/i,
 34 
 35         SHORT_HANDS = Anim.SHORT_HANDS,
 36 
 37         COLORS = [
 38             'backgroundColor' ,
 39             'borderBottomColor' ,
 40             'borderLeftColor' ,
 41             'borderRightColor' ,
 42             'borderTopColor' ,
 43             'color' ,
 44             'outlineColor'
 45         ];
 46 
 47     SHORT_HANDS['background'] = SHORT_HANDS['background'] || [];
 48     SHORT_HANDS['background'].push('backgroundColor');
 49 
 50     SHORT_HANDS['borderColor'] = [
 51         'borderBottomColor',
 52         'borderLeftColor',
 53         'borderRightColor',
 54         'borderTopColor'
 55     ];
 56 
 57     SHORT_HANDS['border'].push(
 58         'borderBottomColor',
 59         'borderLeftColor',
 60         'borderRightColor',
 61         'borderTopColor'
 62     );
 63 
 64     SHORT_HANDS['borderBottom'].push(
 65         'borderBottomColor'
 66     );
 67 
 68     SHORT_HANDS['borderLeft'].push(
 69         'borderLeftColor'
 70     );
 71 
 72     SHORT_HANDS['borderRight'].push(
 73         'borderRightColor'
 74     );
 75 
 76     SHORT_HANDS['borderTop'].push(
 77         'borderTopColor'
 78     );
 79 
 80     //得到颜色的数值表示,红绿蓝数字数组
 81     function numericColor(val) {
 82         val = (val + "");
 83         var match;
 84         if (match = val.match(re_RGB)) {
 85             return [
 86                 parseInt(match[1]),
 87                 parseInt(match[2]),
 88                 parseInt(match[3])
 89             ];
 90         }
 91         else if (match = val.match(re_RGBA)) {
 92             return [
 93                 parseInt(match[1]),
 94                 parseInt(match[2]),
 95                 parseInt(match[3]),
 96                 parseInt(match[4])
 97             ];
 98         }
 99         else if (match = val.match(re_hex)) {
100             for (var i = 1; i < match.length; i++) {
101                 if (match[i].length < 2) {
102                     match[i] += match[i];
103                 }
104             }
105             return [
106                 parseInt(match[1], HEX_BASE),
107                 parseInt(match[2], HEX_BASE),
108                 parseInt(match[3], HEX_BASE)
109             ];
110         }
111         if (KEYWORDS[val = val.toLowerCase()]) {
112             return KEYWORDS[val];
113         }
114 
115         //transparent 或者 颜色字符串返回
116         S.log("only allow rgb or hex color string : " + val, "warn");
117         return [255, 255, 255];
118     }
119 
120     function ColorFx() {
121         ColorFx.superclass.constructor.apply(this, arguments);
122     }
123 
124     S.extend(ColorFx, Fx, {
125 
126         load:function () {
127             var self = this;
128             ColorFx.superclass.load.apply(self, arguments);
129             if (self.from) {
130                 self.from = numericColor(self.from);
131             }
132             if (self.to) {
133                 self.to = numericColor(self.to);
134             }
135         },
136 
137         interpolate:function (from, to, pos) {
138             var interpolate = ColorFx.superclass.interpolate;
139             if (from.length == 3 && to.length == 3) {
140                 return 'rgb(' + [
141                     floor(interpolate(from[0], to[0], pos)),
142                     floor(interpolate(from[1], to[1], pos)),
143                     floor(interpolate(from[2], to[2], pos))
144                 ].join(', ') + ')';
145             } else if (from.length == 4 || to.length == 4) {
146                 return 'rgba(' + [
147                     floor(interpolate(from[0], to[0], pos)),
148                     floor(interpolate(from[1], to[1], pos)),
149                     floor(interpolate(from[2], to[2], pos)),
150                     // 透明度默认 1
151                     floor(interpolate(from[3] || 1, to[3] || 1, pos))
152                 ].join(', ') + ')';
153             } else {
154                 S.log("anim/color unknown value : " + from);
155             }
156         }
157 
158     });
159 
160     S.each(COLORS, function (color) {
161         Fx.Factories[color] = ColorFx;
162     });
163 
164     return ColorFx;
165 
166 }, {
167     requires:["dom", "./base", "./fx"]
168 });
169 
170 /**
171  * TODO
172  * 支持 hsla
173  *  - https://github.com/jquery/jquery-color/blob/master/jquery.color.js
174  **/