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.
323 lines
8.9 KiB
323 lines
8.9 KiB
define(["dojo/_base/array","dojo/_base/lang", "dojo/_base/fx", "dojo/fx", "dojo/dom", "dojo/dom-style", |
|
"dojo/dom-geometry", "dojo/_base/connect", "dojo/_base/html"], |
|
function(arrayUtil, lang, baseFx, coreFx, dom, domStyle, domGeom, connectUtil, htmlUtil){ |
|
|
|
/*===== |
|
return { |
|
// summary: |
|
// Experimental and extended Animations beyond Dojo Core / Base functionality. |
|
// Provides advanced Lines, Animations, and convenience aliases. |
|
}; |
|
=====*/ |
|
|
|
var dojoxFx = lang.getObject("dojox.fx", true); |
|
|
|
lang.mixin(dojoxFx, { |
|
|
|
// anim: Function |
|
// Alias of `dojo.anim` - the shorthand `dojo.animateProperty` with auto-play |
|
anim: baseFx.anim, |
|
|
|
// animateProperty: Function |
|
// Alias of `dojo.animateProperty` - animate any CSS property |
|
animateProperty: baseFx.animateProperty, |
|
|
|
// fadeTo: Function |
|
// Fade an element from an opacity to an opacity. |
|
// Omit `start:` property to detect. `end:` property is required. |
|
// Ultimately an alias to `dojo._fade` |
|
fadeTo: baseFx._fade, |
|
|
|
// fadeIn: Function |
|
// Alias of `dojo.fadeIn` - Fade a node in. |
|
fadeIn: baseFx.fadeIn, |
|
|
|
// fadeOut: Function |
|
// Alias of `dojo.fadeOut` - Fades a node out. |
|
fadeOut: baseFx.fadeOut, |
|
|
|
// combine: Function |
|
// Alias of `dojo.fx.combine` - Run an array of animations in parallel |
|
combine: coreFx.combine, |
|
|
|
// chain: Function |
|
// Alias of `dojo.fx.chain` - Run an array of animations in sequence |
|
chain: coreFx.chain, |
|
|
|
// slideTo: Function |
|
// Alias of `dojo.fx.slideTo` - Slide a node to a defined top/left coordinate |
|
slideTo: coreFx.slideTo, |
|
|
|
// wipeIn: Function |
|
// Alias of `dojo.fx.wipeIn` - Wipe a node to visible |
|
wipeIn: coreFx.wipeIn, |
|
|
|
// wipeOut: Function |
|
// Alias of `dojo.fx.wipeOut` - Wipe a node to non-visible |
|
wipeOut: coreFx.wipeOut |
|
}); |
|
|
|
|
|
dojoxFx.sizeTo = function(/* Object */args){ |
|
// summary: |
|
// Creates an animation that will size a node |
|
// |
|
// description: |
|
// Returns an animation that will size the target node |
|
// defined in args Object about it's center to |
|
// a width and height defined by (args.width, args.height), |
|
// supporting an optional method: chain||combine mixin |
|
// (defaults to chain). |
|
// |
|
// - works best on absolutely or relatively positioned elements |
|
// |
|
// example: |
|
// | // size #myNode to 400px x 200px over 1 second |
|
// | dojo.fx.sizeTo({ |
|
// | node:'myNode', |
|
// | duration: 1000, |
|
// | width: 400, |
|
// | height: 200, |
|
// | method: "combine" |
|
// | }).play(); |
|
// |
|
|
|
var node = args.node = dom.byId(args.node), |
|
abs = "absolute"; |
|
|
|
var method = args.method || "chain"; |
|
if(!args.duration){ args.duration = 500; } // default duration needed |
|
if(method == "chain"){ args.duration = Math.floor(args.duration / 2); } |
|
|
|
var top, newTop, left, newLeft, width, height = null; |
|
|
|
var init = (function(n){ |
|
return function(){ |
|
var cs = domStyle.getComputedStyle(n), |
|
pos = cs.position, |
|
w = cs.width, |
|
h = cs.height |
|
; |
|
|
|
top = (pos == abs ? n.offsetTop : parseInt(cs.top) || 0); |
|
left = (pos == abs ? n.offsetLeft : parseInt(cs.left) || 0); |
|
width = (w == "auto" ? 0 : parseInt(w)); |
|
height = (h == "auto" ? 0 : parseInt(h)); |
|
|
|
newLeft = left - Math.floor((args.width - width) / 2); |
|
newTop = top - Math.floor((args.height - height) / 2); |
|
|
|
if(pos != abs && pos != 'relative'){ |
|
var ret = domStyle.coords(n, true); |
|
top = ret.y; |
|
left = ret.x; |
|
n.style.position = abs; |
|
n.style.top = top + "px"; |
|
n.style.left = left + "px"; |
|
} |
|
} |
|
})(node); |
|
|
|
var anim1 = baseFx.animateProperty(lang.mixin({ |
|
properties: { |
|
height: function(){ |
|
init(); |
|
return { end: args.height || 0, start: height }; |
|
}, |
|
top: function(){ |
|
return { start: top, end: newTop }; |
|
} |
|
} |
|
}, args)); |
|
var anim2 = baseFx.animateProperty(lang.mixin({ |
|
properties: { |
|
width: function(){ |
|
return { start: width, end: args.width || 0 } |
|
}, |
|
left: function(){ |
|
return { start: left, end: newLeft } |
|
} |
|
} |
|
}, args)); |
|
|
|
var anim = coreFx[(args.method == "combine" ? "combine" : "chain")]([anim1, anim2]); |
|
return anim; // dojo.Animation |
|
|
|
}; |
|
|
|
dojoxFx.slideBy = function(/* Object */args){ |
|
// summary: |
|
// Returns an animation to slide a node by a defined offset. |
|
// |
|
// description: |
|
// Returns an animation that will slide a node (args.node) from it's |
|
// current position to it's current posision plus the numbers defined |
|
// in args.top and args.left. standard dojo.fx mixin's apply. |
|
// |
|
// example: |
|
// | // slide domNode 50px down, and 22px left |
|
// | dojox.fx.slideBy({ |
|
// | node: domNode, duration:400, |
|
// | top: 50, left: -22 |
|
// | }).play(); |
|
|
|
var node = args.node = dom.byId(args.node), |
|
top, left; |
|
|
|
var init = (function(n){ |
|
return function(){ |
|
var cs = domStyle.getComputedStyle(n); |
|
var pos = cs.position; |
|
top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0); |
|
left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0); |
|
if(pos != 'absolute' && pos != 'relative'){ |
|
var ret = domGeom.coords(n, true); |
|
top = ret.y; |
|
left = ret.x; |
|
n.style.position = "absolute"; |
|
n.style.top = top + "px"; |
|
n.style.left = left + "px"; |
|
} |
|
} |
|
})(node); |
|
init(); |
|
|
|
var _anim = baseFx.animateProperty(lang.mixin({ |
|
properties: { |
|
// FIXME: is there a way to update the _Line after creation? |
|
// null start values allow chaining to work, animateProperty will |
|
// determine them for us (except in ie6? -- ugh) |
|
top: top + (args.top || 0), |
|
left: left + (args.left || 0) |
|
} |
|
}, args)); |
|
connectUtil.connect(_anim, "beforeBegin", _anim, init); |
|
return _anim; // dojo.Animation |
|
}; |
|
|
|
dojoxFx.crossFade = function(/* Object */args){ |
|
// summary: |
|
// Returns an animation cross fading two element simultaneously |
|
// args: |
|
// - args.nodes: Array - two element array of domNodes, or id's |
|
// |
|
// all other standard animation args mixins apply. args.node ignored. |
|
|
|
// simple check for which node is visible, maybe too simple? |
|
var node1 = args.nodes[0] = dom.byId(args.nodes[0]), |
|
op1 = htmlUtil.style(node1,"opacity"), |
|
node2 = args.nodes[1] = dom.byId(args.nodes[1]), |
|
op2 = htmlUtil.style(node2, "opacity") |
|
; |
|
|
|
var _anim = coreFx.combine([ |
|
baseFx[(op1 == 0 ? "fadeIn" : "fadeOut")](lang.mixin({ |
|
node: node1 |
|
},args)), |
|
baseFx[(op1 == 0 ? "fadeOut" : "fadeIn")](lang.mixin({ |
|
node: node2 |
|
},args)) |
|
]); |
|
return _anim; // dojo.Animation |
|
}; |
|
|
|
dojoxFx.highlight = function(/*Object*/ args){ |
|
// summary: |
|
// Highlight a node |
|
// |
|
// description: |
|
// Returns an animation that sets the node background to args.color |
|
// then gradually fades back the original node background color |
|
// |
|
// example: |
|
// | dojox.fx.highlight({ node:"foo" }).play(); |
|
|
|
var node = args.node = dom.byId(args.node); |
|
|
|
args.duration = args.duration || 400; |
|
|
|
// Assign default color light yellow |
|
var startColor = args.color || '#ffff99', |
|
endColor = htmlUtil.style(node, "backgroundColor") |
|
; |
|
|
|
// safari "fix" |
|
// safari reports rgba(0, 0, 0, 0) (black) as transparent color, while |
|
// other browsers return "transparent", rendered as white by default by |
|
// dojo.Color; now dojo.Color maps "transparent" to |
|
// djConfig.transparentColor ([r, g, b]), if present; so we can use |
|
// the color behind the effect node |
|
if(endColor == "rgba(0, 0, 0, 0)"){ |
|
endColor = "transparent"; |
|
} |
|
|
|
var anim = baseFx.animateProperty(lang.mixin({ |
|
properties: { |
|
backgroundColor: { start: startColor, end: endColor } |
|
} |
|
}, args)); |
|
|
|
if(endColor == "transparent"){ |
|
connectUtil.connect(anim, "onEnd", anim, function(){ |
|
node.style.backgroundColor = endColor; |
|
}); |
|
} |
|
|
|
return anim; // dojo.Animation |
|
}; |
|
|
|
|
|
dojoxFx.wipeTo = function(/*Object*/ args){ |
|
// summary: |
|
// Animate a node wiping to a specific width or height |
|
// |
|
// description: |
|
// Returns an animation that will expand the |
|
// node defined in 'args' object from it's current to |
|
// the height or width value given by the args object. |
|
// |
|
// default to height:, so leave height null and specify width: |
|
// to wipeTo a width. note: this may be deprecated by a |
|
// |
|
// Note that the final value should not include |
|
// units and should be an integer. Thus a valid args object |
|
// would look something like this: |
|
// |
|
// | dojox.fx.wipeTo({ node: "nodeId", height: 200 }).play(); |
|
// |
|
// Node must have no margin/border/padding, so put another |
|
// node inside your target node for additional styling. |
|
|
|
args.node = dom.byId(args.node); |
|
var node = args.node, s = node.style; |
|
|
|
var dir = (args.width ? "width" : "height"), |
|
endVal = args[dir], |
|
props = {} |
|
; |
|
|
|
props[dir] = { |
|
// wrapped in functions so we wait till the last second to query (in case value has changed) |
|
start: function(){ |
|
// start at current [computed] height, but use 1px rather than 0 |
|
// because 0 causes IE to display the whole panel |
|
s.overflow = "hidden"; |
|
if(s.visibility == "hidden" || s.display == "none"){ |
|
s[dir] = "1px"; |
|
s.display = ""; |
|
s.visibility = ""; |
|
return 1; |
|
}else{ |
|
var now = htmlUtil.style(node,dir); |
|
return Math.max(now, 1); |
|
} |
|
}, |
|
end: endVal |
|
}; |
|
|
|
var anim = baseFx.animateProperty(lang.mixin({ properties: props }, args)); |
|
return anim; // dojo.Animation |
|
}; |
|
|
|
return dojoxFx; |
|
});
|
|
|