504 lines
14 KiB
JavaScript
504 lines
14 KiB
JavaScript
|
dojo.provide("dojox.fx.flip");
|
||
|
dojo.experimental("dojox.fx.flip");
|
||
|
dojo.require("dojo.fx");
|
||
|
(function(){
|
||
|
|
||
|
// because ShrinkSafe will eat this up:
|
||
|
var borderConst = "border",
|
||
|
widthConst = "Width",
|
||
|
heightConst = "Height",
|
||
|
topConst = "Top",
|
||
|
rightConst = "Right",
|
||
|
leftConst = "Left",
|
||
|
bottomConst = "Bottom"
|
||
|
;
|
||
|
|
||
|
dojox.fx.flip = function(/*Object*/ args){
|
||
|
// summary: Animate a node flipping following a specific direction
|
||
|
//
|
||
|
// description:
|
||
|
// Returns an animation that will flip the
|
||
|
// node around a central axis:
|
||
|
// if args.dir is "left" or "right" --> y axis
|
||
|
// if args.dir is "top" or "bottom" --> x axis
|
||
|
//
|
||
|
// This effect is obtained using a border distorsion applied to a helper node.
|
||
|
//
|
||
|
// The user can specify three background colors for the helper node:
|
||
|
// darkColor: the darkest color reached during the animation
|
||
|
// lightColor: the brightest color
|
||
|
// endColor: the final backgroundColor for the node
|
||
|
//
|
||
|
// depth: Float
|
||
|
// 0 <= depth <= 1 overrides the computed "depth"
|
||
|
// (0: min distorsion, 1: max distorsion)
|
||
|
//
|
||
|
// whichAnim: String
|
||
|
// "first" : the first half animation
|
||
|
// "last" : the second one
|
||
|
// "both" (default) : both
|
||
|
//
|
||
|
// axis: String
|
||
|
// "center" (default) : the node is flipped around his center
|
||
|
// "shortside" : the node is flipped around his "short" (in perspective) side
|
||
|
// "longside" : the node is flipped around his "long" (in perspective) side
|
||
|
// "cube" : the node flips around the central axis of the cube
|
||
|
//
|
||
|
// shift: Integer
|
||
|
// node translation, perpendicular to the rotation axis
|
||
|
//
|
||
|
// example:
|
||
|
// | var anim = dojox.fx.flip({
|
||
|
// | node: dojo.byId("nodeId"),
|
||
|
// | dir: "top",
|
||
|
// | darkColor: "#555555",
|
||
|
// | lightColor: "#dddddd",
|
||
|
// | endColor: "#666666",
|
||
|
// | depth: .5,
|
||
|
// | shift: 50,
|
||
|
// | duration:300
|
||
|
// | });
|
||
|
|
||
|
var helperNode = dojo.create("div"),
|
||
|
node = args.node = dojo.byId(args.node),
|
||
|
s = node.style,
|
||
|
dims = null,
|
||
|
hs = null,
|
||
|
pn = null,
|
||
|
lightColor = args.lightColor || "#dddddd",
|
||
|
darkColor = args.darkColor || "#555555",
|
||
|
bgColor = dojo.style(node, "backgroundColor"),
|
||
|
endColor = args.endColor || bgColor,
|
||
|
staticProps = {},
|
||
|
anims = [],
|
||
|
duration = args.duration ? args.duration / 2 : 250,
|
||
|
dir = args.dir || "left",
|
||
|
pConst = .9,
|
||
|
transparentColor = "transparent",
|
||
|
whichAnim = args.whichAnim,
|
||
|
axis = args.axis || "center",
|
||
|
depth = args.depth
|
||
|
;
|
||
|
// IE6 workaround: IE6 doesn't support transparent borders
|
||
|
var convertColor = function(color){
|
||
|
return ((new dojo.Color(color)).toHex() === "#000000") ? "#000001" : color;
|
||
|
};
|
||
|
|
||
|
if(dojo.isIE < 7){
|
||
|
endColor = convertColor(endColor);
|
||
|
lightColor = convertColor(lightColor);
|
||
|
darkColor = convertColor(darkColor);
|
||
|
bgColor = convertColor(bgColor);
|
||
|
transparentColor = "black";
|
||
|
helperNode.style.filter = "chroma(color='#000000')";
|
||
|
}
|
||
|
|
||
|
var init = (function(n){
|
||
|
return function(){
|
||
|
var ret = dojo.coords(n, true);
|
||
|
dims = {
|
||
|
top: ret.y,
|
||
|
left: ret.x,
|
||
|
width: ret.w,
|
||
|
height: ret.h
|
||
|
};
|
||
|
}
|
||
|
})(node);
|
||
|
init();
|
||
|
// helperNode initialization
|
||
|
hs = {
|
||
|
position: "absolute",
|
||
|
top: dims["top"] + "px",
|
||
|
left: dims["left"] + "px",
|
||
|
height: "0",
|
||
|
width: "0",
|
||
|
zIndex: args.zIndex || (s.zIndex || 0),
|
||
|
border: "0 solid " + transparentColor,
|
||
|
fontSize: "0",
|
||
|
visibility: "hidden"
|
||
|
};
|
||
|
var props = [ {},
|
||
|
{
|
||
|
top: dims["top"],
|
||
|
left: dims["left"]
|
||
|
}
|
||
|
];
|
||
|
var dynProperties = {
|
||
|
left: [leftConst, rightConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst + "Min", leftConst, "end" + heightConst + "Max"],
|
||
|
right: [rightConst, leftConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst + "Min", leftConst, "end" + heightConst + "Max"],
|
||
|
top: [topConst, bottomConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"],
|
||
|
bottom: [bottomConst, topConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"]
|
||
|
};
|
||
|
// property names
|
||
|
pn = dynProperties[dir];
|
||
|
|
||
|
// .4 <= pConst <= .9
|
||
|
if(typeof depth != "undefined"){
|
||
|
depth = Math.max(0, Math.min(1, depth)) / 2;
|
||
|
pConst = .4 + (.5 - depth);
|
||
|
}else{
|
||
|
pConst = Math.min(.9, Math.max(.4, dims[pn[5].toLowerCase()] / dims[pn[4].toLowerCase()]));
|
||
|
}
|
||
|
var p0 = props[0];
|
||
|
for(var i = 4; i < 6; i++){
|
||
|
if(axis == "center" || axis == "cube"){ // find a better name for "cube"
|
||
|
dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst;
|
||
|
dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst;
|
||
|
}else if(axis == "shortside"){
|
||
|
dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()];
|
||
|
dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst;
|
||
|
}else if(axis == "longside"){
|
||
|
dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst;
|
||
|
dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()];
|
||
|
}
|
||
|
}
|
||
|
if(axis == "center"){
|
||
|
p0[pn[2].toLowerCase()] = dims[pn[2].toLowerCase()] - (dims[pn[8]] - dims[pn[6]]) / 4;
|
||
|
}else if(axis == "shortside"){
|
||
|
p0[pn[2].toLowerCase()] = dims[pn[2].toLowerCase()] - (dims[pn[8]] - dims[pn[6]]) / 2;
|
||
|
}
|
||
|
|
||
|
staticProps[pn[5].toLowerCase()] = dims[pn[5].toLowerCase()] + "px";
|
||
|
staticProps[pn[4].toLowerCase()] = "0";
|
||
|
staticProps[borderConst + pn[1] + widthConst] = dims[pn[4].toLowerCase()] + "px";
|
||
|
staticProps[borderConst + pn[1] + "Color"] = bgColor;
|
||
|
|
||
|
p0[borderConst + pn[1] + widthConst] = 0;
|
||
|
p0[borderConst + pn[1] + "Color"] = darkColor;
|
||
|
p0[borderConst + pn[2] + widthConst] = p0[borderConst + pn[3] + widthConst] = axis != "cube"
|
||
|
? (dims["end" + pn[5] + "Max"] - dims["end" + pn[5] + "Min"]) / 2
|
||
|
: dims[pn[6]] / 2
|
||
|
;
|
||
|
p0[pn[7].toLowerCase()] = dims[pn[7].toLowerCase()] + dims[pn[4].toLowerCase()] / 2 + (args.shift || 0);
|
||
|
p0[pn[5].toLowerCase()] = dims[pn[6]];
|
||
|
|
||
|
var p1 = props[1];
|
||
|
p1[borderConst + pn[0] + "Color"] = { start: lightColor, end: endColor };
|
||
|
p1[borderConst + pn[0] + widthConst] = dims[pn[4].toLowerCase()];
|
||
|
p1[borderConst + pn[2] + widthConst] = 0;
|
||
|
p1[borderConst + pn[3] + widthConst] = 0;
|
||
|
p1[pn[5].toLowerCase()] = { start: dims[pn[6]], end: dims[pn[5].toLowerCase()] };
|
||
|
|
||
|
dojo.mixin(hs, staticProps);
|
||
|
dojo.style(helperNode, hs);
|
||
|
dojo.body().appendChild(helperNode);
|
||
|
|
||
|
var finalize = function(){
|
||
|
// helperNode.parentNode.removeChild(helperNode);
|
||
|
dojo.destroy(helperNode);
|
||
|
// fixes a flicker when the animation ends
|
||
|
s.backgroundColor = endColor;
|
||
|
s.visibility = "visible";
|
||
|
};
|
||
|
if(whichAnim == "last"){
|
||
|
for(i in p0){
|
||
|
p0[i] = { start: p0[i] };
|
||
|
}
|
||
|
p0[borderConst + pn[1] + "Color"] = { start: darkColor, end: endColor };
|
||
|
p1 = p0;
|
||
|
}
|
||
|
if(!whichAnim || whichAnim == "first"){
|
||
|
anims.push(dojo.animateProperty({
|
||
|
node: helperNode,
|
||
|
duration: duration,
|
||
|
properties: p0
|
||
|
}));
|
||
|
}
|
||
|
if(!whichAnim || whichAnim == "last"){
|
||
|
anims.push(dojo.animateProperty({
|
||
|
node: helperNode,
|
||
|
duration: duration,
|
||
|
properties: p1,
|
||
|
onEnd: finalize
|
||
|
}));
|
||
|
}
|
||
|
|
||
|
// hide the original node
|
||
|
dojo.connect(anims[0], "play", function(){
|
||
|
helperNode.style.visibility = "visible";
|
||
|
s.visibility = "hidden";
|
||
|
});
|
||
|
|
||
|
return dojo.fx.chain(anims); // dojo._Animation
|
||
|
|
||
|
}
|
||
|
|
||
|
dojox.fx.flipCube = function(/*Object*/ args){
|
||
|
// summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
|
||
|
//
|
||
|
// description:
|
||
|
// An extension to `dojox.fx.flip` providing a more 3d-like rotation.
|
||
|
// Behaves the same as `dojox.fx.flip`, using the same attributes and
|
||
|
// other standard `dojo._Animation` properties.
|
||
|
//
|
||
|
// example:
|
||
|
// See `dojox.fx.flip`
|
||
|
var anims = [],
|
||
|
mb = dojo.marginBox(args.node),
|
||
|
shiftX = mb.w / 2,
|
||
|
shiftY = mb.h / 2,
|
||
|
dims = {
|
||
|
top: {
|
||
|
pName: "height",
|
||
|
args:[
|
||
|
{
|
||
|
whichAnim: "first",
|
||
|
dir: "top",
|
||
|
shift: -shiftY
|
||
|
},
|
||
|
{
|
||
|
whichAnim: "last",
|
||
|
dir: "bottom",
|
||
|
shift: shiftY
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
right: {
|
||
|
pName: "width",
|
||
|
args:[
|
||
|
{
|
||
|
whichAnim: "first",
|
||
|
dir: "right",
|
||
|
shift: shiftX
|
||
|
},
|
||
|
{
|
||
|
whichAnim: "last",
|
||
|
dir: "left",
|
||
|
shift: -shiftX
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
bottom: {
|
||
|
pName: "height",
|
||
|
args:[
|
||
|
{
|
||
|
whichAnim: "first",
|
||
|
dir: "bottom",
|
||
|
shift: shiftY
|
||
|
},
|
||
|
{
|
||
|
whichAnim: "last",
|
||
|
dir: "top",
|
||
|
shift: -shiftY
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
left: {
|
||
|
pName: "width",
|
||
|
args:[
|
||
|
{
|
||
|
whichAnim: "first",
|
||
|
dir: "left",
|
||
|
shift: -shiftX
|
||
|
},
|
||
|
{
|
||
|
whichAnim: "last",
|
||
|
dir: "right",
|
||
|
shift: shiftX
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
;
|
||
|
var d = dims[args.dir || "left"],
|
||
|
p = d.args
|
||
|
;
|
||
|
args.duration = args.duration ? args.duration * 2 : 500;
|
||
|
args.depth = .8;
|
||
|
args.axis = "cube";
|
||
|
for(var i = p.length - 1; i >= 0; i--){
|
||
|
dojo.mixin(args, p[i]);
|
||
|
anims.push(dojox.fx.flip(args));
|
||
|
}
|
||
|
return dojo.fx.combine(anims);
|
||
|
};
|
||
|
|
||
|
dojox.fx.flipPage = function(/*Object*/ args){
|
||
|
// summary: An extension to `dojox.fx.flip` providing a page flip like animation.
|
||
|
//
|
||
|
// description:
|
||
|
// An extension to `dojox.fx.flip` providing a page flip effect.
|
||
|
// Behaves the same as `dojox.fx.flip`, using the same attributes and
|
||
|
// other standard `dojo._Animation` properties.
|
||
|
//
|
||
|
// example:
|
||
|
// See `dojox.fx.flip`
|
||
|
var n = args.node,
|
||
|
coords = dojo.coords(n, true),
|
||
|
x = coords.x,
|
||
|
y = coords.y,
|
||
|
w = coords.w,
|
||
|
h = coords.h,
|
||
|
bgColor = dojo.style(n, "backgroundColor"),
|
||
|
lightColor = args.lightColor || "#dddddd",
|
||
|
darkColor = args.darkColor,
|
||
|
helperNode = dojo.create("div"),
|
||
|
anims = [],
|
||
|
hn = [],
|
||
|
dir = args.dir || "right",
|
||
|
pn = {
|
||
|
left: ["left", "right", "x", "w"],
|
||
|
top: ["top", "bottom", "y", "h"],
|
||
|
right: ["left", "left", "x", "w"],
|
||
|
bottom: ["top", "top", "y", "h"]
|
||
|
},
|
||
|
shiftMultiplier = {
|
||
|
right: [1, -1],
|
||
|
left: [-1, 1],
|
||
|
top: [-1, 1],
|
||
|
bottom: [1, -1]
|
||
|
}
|
||
|
;
|
||
|
dojo.style(helperNode, {
|
||
|
position: "absolute",
|
||
|
width : w + "px",
|
||
|
height : h + "px",
|
||
|
top : y + "px",
|
||
|
left : x + "px",
|
||
|
visibility: "hidden"
|
||
|
});
|
||
|
var hs = [];
|
||
|
for(var i = 0; i < 2; i++){
|
||
|
var r = i % 2,
|
||
|
d = r ? pn[dir][1] : dir,
|
||
|
wa = r ? "last" : "first",
|
||
|
endColor = r ? bgColor : lightColor,
|
||
|
startColor = r ? endColor : args.startColor || n.style.backgroundColor
|
||
|
;
|
||
|
hn[i] = dojo.clone(helperNode);
|
||
|
var finalize = function(x){
|
||
|
return function(){
|
||
|
dojo.destroy(hn[x]);
|
||
|
}
|
||
|
}(i)
|
||
|
;
|
||
|
dojo.body().appendChild(hn[i]);
|
||
|
hs[i] = {
|
||
|
backgroundColor: r ? startColor : bgColor
|
||
|
};
|
||
|
|
||
|
hs[i][pn[dir][0]] = coords[pn[dir][2]] + shiftMultiplier[dir][0] * i * coords[pn[dir][3]] + "px";
|
||
|
dojo.style(hn[i], hs[i]);
|
||
|
anims.push(dojox.fx.flip({
|
||
|
node: hn[i],
|
||
|
dir: d,
|
||
|
axis: "shortside",
|
||
|
depth: args.depth,
|
||
|
duration: args.duration / 2,
|
||
|
shift: shiftMultiplier[dir][i] * coords[pn[dir][3]] / 2,
|
||
|
darkColor: darkColor,
|
||
|
lightColor: lightColor,
|
||
|
whichAnim: wa,
|
||
|
endColor: endColor
|
||
|
}));
|
||
|
dojo.connect(anims[i], "onEnd", finalize);
|
||
|
}
|
||
|
return dojo.fx.chain(anims);
|
||
|
};
|
||
|
|
||
|
|
||
|
dojox.fx.flipGrid = function(/*Object*/ args){
|
||
|
// summary: An extension to `dojox.fx.flip` providing a decomposition in rows * cols flipping elements
|
||
|
//
|
||
|
// description:
|
||
|
// An extension to `dojox.fx.flip` providing a page flip effect.
|
||
|
// Behaves the same as `dojox.fx.flip`, using the same attributes and
|
||
|
// other standard `dojo._Animation` properties and
|
||
|
//
|
||
|
// cols: Integer columns
|
||
|
// rows: Integer rows
|
||
|
//
|
||
|
// duration: the single flip duration
|
||
|
//
|
||
|
// example:
|
||
|
// See `dojox.fx.flip`
|
||
|
var rows = args.rows || 4,
|
||
|
cols = args.cols || 4,
|
||
|
anims = [],
|
||
|
helperNode = dojo.create("div"),
|
||
|
n = args.node,
|
||
|
coords = dojo.coords(n, true),
|
||
|
x = coords.x,
|
||
|
y = coords.y,
|
||
|
nw = coords.w,
|
||
|
nh = coords.h,
|
||
|
w = coords.w / cols,
|
||
|
h = coords.h / rows,
|
||
|
cAnims = []
|
||
|
;
|
||
|
dojo.style(helperNode, {
|
||
|
position: "absolute",
|
||
|
width: w + "px",
|
||
|
height: h + "px",
|
||
|
backgroundColor: dojo.style(n, "backgroundColor")
|
||
|
});
|
||
|
for(var i = 0; i < rows; i++){
|
||
|
var r = i % 2,
|
||
|
d = r ? "right" : "left",
|
||
|
signum = r ? 1 : -1
|
||
|
;
|
||
|
// cloning
|
||
|
var cn = dojo.clone(n);
|
||
|
dojo.style(cn, {
|
||
|
position: "absolute",
|
||
|
width: nw + "px",
|
||
|
height: nh + "px",
|
||
|
top: y + "px",
|
||
|
left: x + "px",
|
||
|
clip: "rect(" + i * h + "px," + nw + "px," + nh + "px,0)"
|
||
|
});
|
||
|
dojo.body().appendChild(cn);
|
||
|
anims[i] = [];
|
||
|
for(var j = 0; j < cols; j++){
|
||
|
var hn = dojo.clone(helperNode),
|
||
|
l = r ? j : cols - (j + 1)
|
||
|
;
|
||
|
var adjustClip = function(xn, yCounter, xCounter){
|
||
|
return function(){
|
||
|
if(!(yCounter % 2)){
|
||
|
dojo.style(xn, {
|
||
|
clip: "rect(" + yCounter * h + "px," + (nw - (xCounter + 1) * w ) + "px," + ((yCounter + 1) * h) + "px,0px)"
|
||
|
});
|
||
|
}else{
|
||
|
dojo.style(xn, {
|
||
|
clip: "rect(" + yCounter * h + "px," + nw + "px," + ((yCounter + 1) * h) + "px," + ((xCounter + 1) * w) + "px)"
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}(cn, i, j);
|
||
|
dojo.body().appendChild(hn);
|
||
|
dojo.style(hn, {
|
||
|
left: x + l * w + "px",
|
||
|
top: y + i * h + "px",
|
||
|
visibility: "hidden"
|
||
|
});
|
||
|
var a = dojox.fx.flipPage({
|
||
|
node: hn,
|
||
|
dir: d,
|
||
|
duration: args.duration || 900,
|
||
|
shift: signum * w/2,
|
||
|
depth: .2,
|
||
|
darkColor: args.darkColor,
|
||
|
lightColor: args.lightColor,
|
||
|
startColor: args.startColor || args.node.style.backgroundColor
|
||
|
}),
|
||
|
removeHelper = function(xn){
|
||
|
return function(){
|
||
|
dojo.destroy(xn);
|
||
|
}
|
||
|
}(hn)
|
||
|
;
|
||
|
dojo.connect(a, "play", this, adjustClip);
|
||
|
dojo.connect(a, "play", this, removeHelper);
|
||
|
anims[i].push(a);
|
||
|
}
|
||
|
cAnims.push(dojo.fx.chain(anims[i]));
|
||
|
|
||
|
}
|
||
|
dojo.connect(cAnims[0], "play", function(){
|
||
|
dojo.style(n, {visibility: "hidden"});
|
||
|
});
|
||
|
return dojo.fx.combine(cAnims);
|
||
|
};
|
||
|
})();
|