228 lines
7.5 KiB
JavaScript
228 lines
7.5 KiB
JavaScript
|
dojo.provide("dojox.fx.style");
|
||
|
dojo.experimental("dojox.fx.style");
|
||
|
//
|
||
|
// summary: dojox.fx CSS Class _Animations:
|
||
|
//
|
||
|
// description: a set of functions to animate properties based on
|
||
|
// normalized CSS class definitions.
|
||
|
//
|
||
|
// provides: addClass, removeClass, and toggleClass
|
||
|
//
|
||
|
dojo.require("dojo.fx");
|
||
|
|
||
|
// FIXME: should the call signatures match dojo.addClass/removeClass/toggleClass and extend
|
||
|
// by having a third (or fourth) param to mix in additional _Animation args for advanced
|
||
|
// usage (delay: curve: repeat: easing: etc ... )
|
||
|
(function(){
|
||
|
|
||
|
var d = dojo;
|
||
|
|
||
|
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, calculcated values (no keys), to be normalized/compared
|
||
|
// elsewhere
|
||
|
return d.map(dojox.fx._allowedProperties,function(style){
|
||
|
return cache[style]; // String
|
||
|
}); // Array
|
||
|
};
|
||
|
|
||
|
var _getCalculatedStyleChanges = function(/*dojox.fx._arg.StyleArgs*/ args, /*Boolean*/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
|
||
|
// iterateing 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
|
||
|
|
||
|
var node = args.node = d.byId(args.node);
|
||
|
var cs = d.getComputedStyle(node);
|
||
|
|
||
|
// take our snapShots
|
||
|
var _before = _getStyleSnapshot(cs);
|
||
|
d[(addClass ? "addClass" : "removeClass")](node, args.cssClass);
|
||
|
var _after = _getStyleSnapshot(cs);
|
||
|
d[(addClass ? "removeClass" : "addClass")](node, args.cssClass);
|
||
|
|
||
|
var calculated = {}, i = 0;
|
||
|
d.forEach(dojox.fx._allowedProperties,function(prop){
|
||
|
if(_before[i] != _after[i]){
|
||
|
// FIXME: the static unit: px is not good, either. need to parse unit from computed style?
|
||
|
calculated[prop] = parseInt(_after[i]) /* start: parseInt(_before[i]), unit: 'px' */ ;
|
||
|
}
|
||
|
i++;
|
||
|
});
|
||
|
return calculated;
|
||
|
};
|
||
|
|
||
|
d.mixin(dojox.fx,{
|
||
|
|
||
|
addClass: function(/* dojox.fx._arg.StyleArgs */ 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)
|
||
|
//
|
||
|
// 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({ node:"test", cssClass:"foo" }).play();
|
||
|
//
|
||
|
var node = args.node = d.byId(args.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(){
|
||
|
d.addClass(n, args.cssClass);
|
||
|
n.style.cssText = _beforeStyle;
|
||
|
}
|
||
|
})(node);
|
||
|
|
||
|
// _getCalculatedStleChanges is the core of our style/class animations
|
||
|
var mixedProperties = _getCalculatedStyleChanges(args,true);
|
||
|
var _beforeStyle = node.style.cssText;
|
||
|
var _anim = d.animateProperty(d.mixin({
|
||
|
properties: mixedProperties
|
||
|
}, args));
|
||
|
d.connect(_anim, "onEnd", _anim,pushClass);
|
||
|
return _anim; // dojo._Animation
|
||
|
},
|
||
|
|
||
|
removeClass: function(/*dojox.fx._arg.StyleArgs*/ 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({
|
||
|
// | node: "bar",
|
||
|
// | cssClass: "foo"
|
||
|
// | }).play();
|
||
|
|
||
|
var node = (args.node = dojo.byId(args.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(){
|
||
|
d.removeClass(n, args.cssClass);
|
||
|
n.style.cssText = _beforeStyle;
|
||
|
}
|
||
|
})(node);
|
||
|
|
||
|
var mixedProperties = _getCalculatedStyleChanges(args, false);
|
||
|
var _beforeStyle = node.style.cssText;
|
||
|
var _anim = d.animateProperty(d.mixin({
|
||
|
properties: mixedProperties
|
||
|
}, args));
|
||
|
d.connect(_anim, "onEnd", _anim, pullClass);
|
||
|
return _anim; // dojo._Animation
|
||
|
},
|
||
|
|
||
|
toggleClass: function(/*DomNode|String*/node, /*String*/cssClass, /*Boolean?*/condition){
|
||
|
// 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:
|
||
|
// The domNode (or string of the id) to toggle
|
||
|
// cssClass:
|
||
|
// String of the classname to add to the node
|
||
|
// condition:
|
||
|
// If passed, true means to add the class, false means to remove.
|
||
|
//
|
||
|
// 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 = !d.hasClass(node, cssClass);
|
||
|
}
|
||
|
return dojox.fx[(condition ? "addClass" : "removeClass")]({ node: node, cssClass:cssClass }); // dojo._Animation
|
||
|
// TODO: support 4th param animMixin to allow passing of easing and duration and other _Animtion options
|
||
|
},
|
||
|
|
||
|
_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"
|
||
|
]
|
||
|
|
||
|
});
|
||
|
|
||
|
})();
|