You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
7.6 KiB
227 lines
7.6 KiB
define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base","dojo/_base/array","dojo/dom","dojo/dom-style","dojo/dom-class", |
|
"dojo/_base/connect"], |
|
function(dojo,lang,baseFx,coreFx,dojoxFx,arrayUtil,dom,domStyle,domClass,connectUtil){ |
|
dojo.experimental("dojox.fx.style"); |
|
|
|
|
|
var _getStyleSnapshot = function(/* Object */cache){ |
|
// summary: |
|
// uses a dojo.getComputedStyle(node) cache reference and |
|
// iterates through the 'documented/supported animate-able' |
|
// properties. |
|
// |
|
// returns: Array |
|
// an array of raw, calculated values (no keys), to be normalized/compared |
|
// elsewhere |
|
return arrayUtil.map(dojoxFx._allowedProperties, function(style){ |
|
return cache[style]; // String |
|
}); // Array |
|
}; |
|
|
|
var _getCalculatedStyleChanges = function(node, cssClass, addClass){ |
|
// summary: |
|
// Calculate the difference in style properties between two states |
|
// description: |
|
// calculate and normalize(?) the differences between two states |
|
// of a node (args.node) by quickly adding or removing a class, and |
|
// iterating over the results of dojox.fx._getStyleSnapshot() |
|
// addClass: |
|
// true to calculate what adding a class would do, |
|
// false to calculate what removing the class would do |
|
|
|
node = dom.byId(node); |
|
var cs = domStyle.getComputedStyle(node); |
|
|
|
// take our snapShots |
|
var _before = _getStyleSnapshot(cs); |
|
dojo[(addClass ? "addClass" : "removeClass")](node, cssClass); |
|
var _after = _getStyleSnapshot(cs); |
|
dojo[(addClass ? "removeClass" : "addClass")](node, cssClass); |
|
|
|
var calculated = {}, i = 0; |
|
arrayUtil.forEach(dojoxFx._allowedProperties, function(prop){ |
|
if(_before[i] != _after[i]){ |
|
// FIXME: the static units: px is not good, either. need to parse unit from computed style? |
|
calculated[prop] = parseInt(_after[i]) /* start: parseInt(_before[i]), units: 'px' */ ; |
|
} |
|
i++; |
|
}); |
|
return calculated; |
|
}; |
|
|
|
var styleFx = { |
|
// summary: |
|
// dojox.fx CSS Class Animations |
|
// description: |
|
// a set of functions to animate properties based on |
|
// normalized CSS class definitions. |
|
|
|
addClass: function(node, cssClass, args){ |
|
// summary: |
|
// Animate the effects of adding a class to a node |
|
// description: |
|
// Creates an animation that will animate |
|
// the properties of a node to the properties |
|
// defined in a standard CSS .class definition. |
|
// (calculating the differences itself) |
|
// node: String|DomNode |
|
// A String ID or DomNode referce to animate |
|
// cssClass: String |
|
// The CSS class name to add to the node |
|
// args: Object? |
|
// Additional optional `dojo.animateProperty` arguments, such as |
|
// duration, easing and so on. |
|
// example: |
|
// | |
|
// | .bar { line-height: 12px; } |
|
// | .foo { line-height: 40px; } |
|
// | <div class="bar" id="test"> |
|
// | Multi<br>line<br>text |
|
// | </div> |
|
// | |
|
// | // animate to line-height:40px |
|
// | dojo.fx.addClass("test", "foo").play(); |
|
// |
|
node = dom.byId(node); |
|
|
|
var pushClass = (function(n){ |
|
// summary: |
|
// onEnd we want to add the class to the node |
|
// (as dojo.addClass naturally would) in case our |
|
// class parsing misses anything the browser would |
|
// otherwise interpret. this may cause some flicker, |
|
// and will only apply the class so children can inherit |
|
// after the animation is done (potentially more flicker) |
|
return function(){ |
|
domClass.add(n, cssClass); |
|
n.style.cssText = _beforeStyle; |
|
} |
|
})(node); |
|
|
|
// _getCalculatedStleChanges is the core of our style/class animations |
|
var mixedProperties = _getCalculatedStyleChanges(node, cssClass, true); |
|
var _beforeStyle = node.style.cssText; |
|
var _anim = baseFx.animateProperty(lang.mixin({ |
|
node: node, |
|
properties: mixedProperties |
|
}, args)); |
|
connectUtil.connect(_anim, "onEnd", _anim, pushClass); |
|
return _anim; // dojo.Animation |
|
}, |
|
|
|
removeClass: function(node, cssClass, args){ |
|
// summary: |
|
// Animate the effects of removing a class from a node |
|
// description: |
|
// Creates an animation that will animate the properties of a |
|
// node (args.node) to the properties calculated after removing |
|
// a standard CSS className from a that node. |
|
// |
|
// calls dojo.removeClass(args.cssClass) onEnd of animation |
|
// |
|
// standard dojo.Animation object rules apply. |
|
// example: |
|
// | // animate the removal of "foo" from a node with id="bar" |
|
// | dojox.fx.removeClass("bar", "foo").play() |
|
|
|
node = dom.byId(node); |
|
|
|
var pullClass = (function(n){ |
|
// summary: |
|
// onEnd we want to remove the class from the node |
|
// (as dojo.removeClass naturally would) in case our class |
|
// parsing misses anything the browser would otherwise |
|
// interpret. this may cause some flicker, and will only |
|
// apply the class so children can inherit after the |
|
// animation is done (potentially more flicker) |
|
|
|
return function(){ |
|
domClass.remove(n, cssClass); |
|
n.style.cssText = _beforeStyle; |
|
} |
|
})(node); |
|
|
|
var mixedProperties = _getCalculatedStyleChanges(node, cssClass); |
|
var _beforeStyle = node.style.cssText; |
|
var _anim = baseFx.animateProperty(lang.mixin({ |
|
node: node, |
|
properties: mixedProperties |
|
}, args)); |
|
connectUtil.connect(_anim, "onEnd", _anim, pullClass); |
|
return _anim; // dojo.Animation |
|
}, |
|
|
|
toggleClass: function(node, cssClass, condition, args){ |
|
// summary: |
|
// Animate the effects of Toggling a class on a Node |
|
// description: |
|
// creates an animation that will animate the effect of |
|
// toggling a class on or off of a node. |
|
// Adds a class to node if not present, or removes if present. |
|
// Pass a boolean condition if you want to explicitly add or remove. |
|
// node: String|DomNode |
|
// The domNode (or string of the id) to toggle |
|
// cssClass: String |
|
// String of the classname to add to the node |
|
// condition: Boolean? |
|
// If passed, true means to add the class, false means to remove. |
|
// args: Object? |
|
// Additional `dojo.Animation` args to pass along. |
|
// example: |
|
// | // add the class "sampleClass" to a node id="theNode" |
|
// | dojox.fx.toggleClass("theNode","sampleClass",true).play(); |
|
// example: |
|
// | // toggle the class "sampleClass" on the node id="theNode" |
|
// | dojox.fx.toggleClass("theNode","sampleClass").play(); |
|
|
|
if(typeof condition == "undefined"){ |
|
condition = !domClass.contains(node, cssClass); |
|
} |
|
return dojoxFx[(condition ? "addClass" : "removeClass")](node, cssClass, args); // dojo.Animation |
|
}, |
|
|
|
_allowedProperties: [ |
|
// summary: |
|
// Our pseudo map of properties we will check for. |
|
// description: |
|
// it should be much more intuitive. a way to normalize and |
|
// "predict" intent, or even something more clever ... |
|
// open to suggestions. |
|
|
|
// no-brainers: |
|
"width", |
|
"height", |
|
// only if position = absolute || relative? |
|
"left", "top", // "right", "bottom", |
|
// these need to be filtered through dojo.colors? |
|
// "background", // normalize to: |
|
/* "backgroundImage", */ |
|
// "backgroundPosition", // FIXME: to be effective, this needs "#px #px"? |
|
"backgroundColor", |
|
|
|
"color", |
|
|
|
// "border", |
|
//"borderBottomColor", |
|
"borderBottomWidth", |
|
//"borderTopColor", |
|
"borderTopWidth", |
|
//"borderLeftColor", |
|
"borderLeftWidth", |
|
//"borderRightColor", |
|
"borderRightWidth", |
|
|
|
// "padding", // normalize to: |
|
"paddingLeft", "paddingRight", "paddingTop", "paddingBottom", |
|
// "margin", // normalize to: |
|
"marginLeft", "marginTop", "marginRight", "marginBottom", |
|
|
|
// unit import/delicate?: |
|
"lineHeight", |
|
"letterSpacing", |
|
"fontSize" |
|
] |
|
}; |
|
lang.mixin(dojoxFx,styleFx); |
|
return styleFx; |
|
});
|
|
|