6 description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.
8 license: MIT-style license.
10 requires: [Fx, Element.Style]
21 //prepares the base from/to object
23 prepare: function(element, property, values){
24 values = Array.from(values);
25 var from = values[0], to = values[1];
28 from = element.getStyle(property);
29 var unit = this.options.unit;
30 // adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299
31 if (unit && from && typeof from == 'string' && from.slice(-unit.length) != unit && parseFloat(from) != 0){
32 element.setStyle(property, to + unit);
33 var value = element.getComputedStyle(property);
34 // IE and Opera support pixelLeft or pixelWidth
35 if (!(/px$/.test(value))){
36 value = element.style[('pixel-' + property).camelCase()];
38 // adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
39 var left = element.style.left;
40 element.style.left = to + unit;
41 value = element.style.pixelLeft;
42 element.style.left = left;
45 from = (to || 1) / (parseFloat(value) || 1) * (parseFloat(from) || 0);
46 element.setStyle(property, from + unit);
49 return {from: this.parse(from), to: this.parse(to)};
52 //parses a value into an array
54 parse: function(value){
55 value = Function.from(value)();
56 value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
57 return value.map(function(val){
60 Object.each(Fx.CSS.Parsers, function(parser, key){
62 var parsed = parser.parse(val);
63 if (parsed || parsed === 0) found = {value: parsed, parser: parser};
65 found = found || {value: val, parser: Fx.CSS.Parsers.String};
70 //computes by a from and to prepared objects, using their parsers.
72 compute: function(from, to, delta){
74 (Math.min(from.length, to.length)).times(function(i){
75 computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
77 computed.$family = Function.from('fx:css:value');
81 //serves the value as settable
83 serve: function(value, unit){
84 if (typeOf(value) != 'fx:css:value') value = this.parse(value);
86 value.each(function(bit){
87 returned = returned.concat(bit.parser.serve(bit.value, unit));
92 //renders the change to an element
94 render: function(element, property, value, unit){
95 element.setStyle(property, this.serve(value, unit));
98 //searches inside the page css to find the values for a selector
100 search: function(selector){
101 if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
102 var to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');
104 var searchStyles = function(rules){
105 Array.each(rules, function(rule, i){
107 searchStyles(rule.rules || rule.cssRules);
110 if (!rule.style) return;
111 var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
112 return m.toLowerCase();
114 if (!selectorText || !selectorTest.test(selectorText)) return;
115 Object.each(Element.Styles, function(value, style){
116 if (!rule.style[style] || Element.ShortStyles[style]) return;
117 value = String(rule.style[style]);
118 to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;
123 Array.each(document.styleSheets, function(sheet, j){
124 var href = sheet.href;
125 if (href && href.indexOf('://') > -1 && href.indexOf(document.domain) == -1) return;
126 var rules = sheet.rules || sheet.cssRules;
129 return Fx.CSS.Cache[selector] = to;
139 parse: function(value){
140 if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
141 return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
143 compute: function(from, to, delta){
144 return from.map(function(value, i){
145 return Math.round(Fx.compute(from[i], to[i], delta));
148 serve: function(value){
149 return value.map(Number);
156 serve: function(value, unit){
157 return (unit) ? value + unit : value;
162 parse: Function.from(false),
163 compute: function(zero, one){
166 serve: function(zero){
175 Fx.CSS.Parsers = new Hash(Fx.CSS.Parsers);