- Author:
- David Nickerson <nickerso@users.sourceforge.net>
- Date:
- 2009-07-16 02:00:03+12:00
- Desc:
- the starting point for the HH tutorial example
- Permanent Source URI:
- https://models.fieldml.org/workspace/a1/rawfile/f6a8f90307388eb4b040ee3566b84d88b59247f7/dojo-presentation/js/dojo/dojox/fx/style.js
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("dojox.fx._base");
// 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 ... )
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 = dojo.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(){
dojo.addClass(n, args.cssClass);
n.style.cssText = _beforeStyle;
}
})(node);
// _getCalculatedStleChanges is the core of our style/class animations
var mixedProperties = dojox.fx._getCalculatedStyleChanges(args,true);
var _beforeStyle = node.style.cssText;
var _anim = dojo.animateProperty(dojo.mixin({
properties: mixedProperties
},args));
dojo.connect(_anim,"onEnd",_anim,pushClass);
return _anim; // dojo._Animation
};
dojox.fx.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(){
dojo.removeClass(n, args.cssClass);
n.style.cssText = _beforeStyle;
}
})(node);
var mixedProperties = dojox.fx._getCalculatedStyleChanges(args,false);
var _beforeStyle = node.style.cssText;
var _anim = dojo.animateProperty(dojo.mixin({
properties: mixedProperties
},args));
dojo.connect(_anim,"onEnd",_anim,pullClass);
return _anim; // dojo._Animation
};
dojox.fx.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 = !dojo.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
};
dojox.fx._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"
];
dojox.fx._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 dojo.map(dojox.fx._allowedProperties,function(style){
return cache[style]; // String
}); // Array
};
dojox.fx._getCalculatedStyleChanges = function(/*dojox.fx._arg.StyleArgs*/ args, /*Boolean*/addClass){
// summary: calclate 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 = dojo.byId(args.node);
var cs = dojo.getComputedStyle(node);
// take our snapShots
var _before = dojox.fx._getStyleSnapshot(cs);
dojo[(addClass ? "addClass" : "removeClass")](node,args.cssClass);
var _after = dojox.fx._getStyleSnapshot(cs);
dojo[(addClass ? "removeClass" : "addClass")](node,args.cssClass);
var calculated = {};
var i = 0;
dojo.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;
};