source: Dev/branches/rest-dojo-ui/client/dojox/fx/flip.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 14.2 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/html",
4        "dojo/dom",
5        "dojo/dom-construct",
6        "dojo/dom-geometry",
7        "dojo/_base/connect",
8        "dojo/_base/Color",
9        "dojo/_base/sniff",
10        "dojo/_base/lang",
11        "dojo/_base/window",
12        "dojo/_base/fx",
13        "dojo/fx",
14        "./_base"
15], function(kernel, htmlUtil, dom, domConstruct, domGeom, connectUtil, Color, has, lang, winUtil, baseFx, coreFx, fxExt) {
16//kernel,lang->(sniff,array,has),sniff,unload,window
17
18        kernel.experimental("dojox.fx.flip");
19        // because ShrinkSafe will eat this up:
20        var borderConst = "border",
21                widthConst = "Width",
22                heightConst = "Height",
23                topConst = "Top",
24                rightConst = "Right",
25                leftConst = "Left",
26                bottomConst = "Bottom"
27        ;
28
29        fxExt.flip = function(/*Object*/ args){
30                // summary: Animate a node flipping following a specific direction
31                //
32                // description:
33                //              Returns an animation that will flip the
34                //              node around a central axis:
35                //              if args.dir is "left" or "right" --> y axis
36                //              if args.dir is "top" or "bottom" --> x axis
37                //
38                //              This effect is obtained using a border distorsion applied to a helper node.
39                //
40                //              The user can specify three background colors for the helper node:
41                //              darkColor: the darkest color reached during the animation
42                //              lightColor: the brightest color
43                //              endColor: the final backgroundColor for the node
44                //
45                //              depth: Float
46                //                       0 <= depth <= 1 overrides the computed "depth"
47                //                      (0: min distorsion, 1: max distorsion)
48                //
49                //              whichAnim: String
50                //                      "first"                  : the first half animation
51                //                      "last"                   : the second one
52                //                      "both" (default) : both
53                //
54                //              axis: String
55                //                      "center" (default)        : the node is flipped around his center
56                //                      "shortside"                       : the node is flipped around his "short" (in perspective) side
57                //                      "longside"                        : the node is flipped around his "long" (in perspective) side
58                //                      "cube"                            : the node flips around the central axis of the cube
59                //
60                //              shift: Integer
61                //                      node translation, perpendicular to the rotation axis
62                //
63                //      example:
64                //      |       var anim = dojox.fx.flip({
65                //      |               node: dojo.byId("nodeId"),
66                //      |               dir: "top",
67                //      |               darkColor: "#555555",
68                //      |               lightColor: "#dddddd",
69                //      |               endColor: "#666666",
70                //      |               depth: .5,
71                //      |               shift: 50,
72                //      |               duration:300
73                //      |         });
74
75                var helperNode = domConstruct.create("div"),
76                        node = args.node = dom.byId(args.node),
77                        s = node.style,
78                        dims = null,
79                        hs = null,
80                        pn = null,
81                        lightColor = args.lightColor || "#dddddd",
82                        darkColor = args.darkColor || "#555555",
83                        bgColor = htmlUtil.style(node, "backgroundColor"),
84                        endColor = args.endColor || bgColor,
85                        staticProps = {},
86                        anims = [],
87                        duration = args.duration ? args.duration / 2 : 250,
88                        dir = args.dir || "left",
89                        pConst = .9,
90                        transparentColor = "transparent",
91                        whichAnim = args.whichAnim,
92                        axis = args.axis || "center",
93                        depth = args.depth
94                ;
95                // IE6 workaround: IE6 doesn't support transparent borders
96                var convertColor = function(color){
97                        return ((new Color(color)).toHex() === "#000000") ? "#000001" : color;
98                };
99
100                if(has("ie") < 7){
101                        endColor = convertColor(endColor);
102                        lightColor = convertColor(lightColor);
103                        darkColor = convertColor(darkColor);
104                        bgColor = convertColor(bgColor);
105                        transparentColor = "black";
106                        helperNode.style.filter = "chroma(color='#000000')";
107                }
108
109                var init = (function(n){
110                        return function(){
111                                var ret = htmlUtil.coords(n, true);
112                                dims = {
113                                        top: ret.y,
114                                        left: ret.x,
115                                        width: ret.w,
116                                        height: ret.h
117                                };
118                        }
119                })(node);
120                init();
121                // helperNode initialization
122                hs = {
123                        position: "absolute",
124                        top: dims["top"] + "px",
125                        left: dims["left"] + "px",
126                        height: "0",
127                        width: "0",
128                        zIndex: args.zIndex || (s.zIndex || 0),
129                        border: "0 solid " + transparentColor,
130                        fontSize: "0",
131                        visibility: "hidden"
132                };
133                var props = [ {},
134                        {
135                                top: dims["top"],
136                                left: dims["left"]
137                        }
138                ];
139                var dynProperties = {
140                        left: [leftConst, rightConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst + "Min", leftConst, "end" + heightConst + "Max"],
141                        right: [rightConst, leftConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst + "Min", leftConst, "end" + heightConst + "Max"],
142                        top: [topConst, bottomConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"],
143                        bottom: [bottomConst, topConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"]
144                };
145                // property names
146                pn = dynProperties[dir];
147
148                // .4 <= pConst <= .9
149                if(typeof depth != "undefined"){
150                        depth = Math.max(0, Math.min(1, depth)) / 2;
151                        pConst = .4 + (.5 - depth);
152                }else{
153                        pConst = Math.min(.9, Math.max(.4, dims[pn[5].toLowerCase()] / dims[pn[4].toLowerCase()]));
154                }
155                var p0 = props[0];
156                for(var i = 4; i < 6; i++){
157                        if(axis == "center" || axis == "cube"){ // find a better name for "cube"
158                                dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst;
159                                dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst;
160                        }else if(axis == "shortside"){
161                                dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()];
162                                dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst;
163                        }else if(axis == "longside"){
164                                dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst;
165                                dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()];
166                        }
167                }
168                if(axis == "center"){
169                        p0[pn[2].toLowerCase()] = dims[pn[2].toLowerCase()] - (dims[pn[8]] - dims[pn[6]]) / 4;
170                }else if(axis == "shortside"){
171                        p0[pn[2].toLowerCase()] = dims[pn[2].toLowerCase()] - (dims[pn[8]] - dims[pn[6]]) / 2;
172                }
173
174                staticProps[pn[5].toLowerCase()] = dims[pn[5].toLowerCase()] + "px";
175                staticProps[pn[4].toLowerCase()] = "0";
176                staticProps[borderConst + pn[1] + widthConst] = dims[pn[4].toLowerCase()] + "px";
177                staticProps[borderConst + pn[1] + "Color"] = bgColor;
178
179                p0[borderConst + pn[1] + widthConst] = 0;
180                p0[borderConst + pn[1] + "Color"] = darkColor;
181                p0[borderConst + pn[2] + widthConst] = p0[borderConst + pn[3] + widthConst] = axis != "cube"
182                        ? (dims["end" + pn[5] +  "Max"] - dims["end" + pn[5] + "Min"]) / 2
183                        : dims[pn[6]] / 2
184                ;
185                p0[pn[7].toLowerCase()] = dims[pn[7].toLowerCase()] + dims[pn[4].toLowerCase()] / 2 + (args.shift || 0);
186                p0[pn[5].toLowerCase()] = dims[pn[6]];
187
188                var p1 = props[1];
189                p1[borderConst + pn[0] + "Color"] = { start: lightColor, end: endColor };
190                p1[borderConst + pn[0] + widthConst] = dims[pn[4].toLowerCase()];
191                p1[borderConst + pn[2] + widthConst] = 0;
192                p1[borderConst + pn[3] + widthConst] = 0;
193                p1[pn[5].toLowerCase()] = { start: dims[pn[6]], end: dims[pn[5].toLowerCase()] };
194
195                lang.mixin(hs, staticProps);
196                htmlUtil.style(helperNode, hs);
197                winUtil.body().appendChild(helperNode);
198
199                var finalize = function(){
200//                      helperNode.parentNode.removeChild(helperNode);
201                        domConstruct.destroy(helperNode);
202                        // fixes a flicker when the animation ends
203                        s.backgroundColor = endColor;
204                        s.visibility = "visible";
205                };
206                if(whichAnim == "last"){
207                        for(i in p0){
208                                p0[i] = { start: p0[i] };
209                        }
210                        p0[borderConst + pn[1] + "Color"] = { start: darkColor, end: endColor };
211                        p1 = p0;
212                }
213                if(!whichAnim || whichAnim == "first"){
214                        anims.push(baseFx.animateProperty({
215                                node: helperNode,
216                                duration: duration,
217                                properties: p0
218                        }));
219                }
220                if(!whichAnim || whichAnim == "last"){
221                        anims.push(baseFx.animateProperty({
222                                node: helperNode,
223                                duration: duration,
224                                properties: p1,
225                                onEnd: finalize
226                        }));
227                }
228
229                // hide the original node
230                connectUtil.connect(anims[0], "play", function(){
231                        helperNode.style.visibility = "visible";
232                        s.visibility = "hidden";
233                });
234
235                return coreFx.chain(anims); // dojo.Animation
236
237        }
238
239        fxExt.flipCube = function(/*Object*/ args){
240                // summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
241                //
242                // description:
243                //              An extension to `dojox.fx.flip` providing a more 3d-like rotation.
244                //              Behaves the same as `dojox.fx.flip`, using the same attributes and
245                //              other standard `dojo.Animation` properties.
246                //
247                //      example:
248                //              See `dojox.fx.flip`
249                var anims = [],
250                        mb = domGeom.getMarginBox(args.node),
251                        shiftX = mb.w / 2,
252                        shiftY = mb.h / 2,
253                        dims = {
254                                top: {
255                                        pName: "height",
256                                        args:[
257                                                {
258                                                        whichAnim: "first",
259                                                        dir: "top",
260                                                        shift: -shiftY
261                                                },
262                                                {
263                                                        whichAnim: "last",
264                                                        dir: "bottom",
265                                                        shift: shiftY
266                                                }
267                                        ]
268                                },
269                                right: {
270                                        pName: "width",
271                                        args:[
272                                                {
273                                                        whichAnim: "first",
274                                                        dir: "right",
275                                                        shift: shiftX
276                                                },
277                                                {
278                                                        whichAnim: "last",
279                                                        dir: "left",
280                                                        shift: -shiftX
281                                                }
282                                        ]
283                                },
284                                bottom: {
285                                        pName: "height",
286                                        args:[
287                                                {
288                                                        whichAnim: "first",
289                                                        dir: "bottom",
290                                                        shift: shiftY
291                                                },
292                                                {
293                                                        whichAnim: "last",
294                                                        dir: "top",
295                                                        shift: -shiftY
296                                                }
297                                        ]
298                                },
299                                left: {
300                                        pName: "width",
301                                        args:[
302                                                {
303                                                        whichAnim: "first",
304                                                        dir: "left",
305                                                        shift: -shiftX
306                                                },
307                                                {
308                                                        whichAnim: "last",
309                                                        dir: "right",
310                                                        shift: shiftX
311                                                }
312                                        ]
313                                }
314                        }
315                ;
316                var d = dims[args.dir || "left"],
317                        p = d.args
318                ;
319                args.duration = args.duration ? args.duration * 2 : 500;
320                args.depth = .8;
321                args.axis = "cube";
322                for(var i = p.length - 1; i >= 0; i--){
323                        lang.mixin(args, p[i]);
324                        anims.push(fxExt.flip(args));
325                }
326                return coreFx.combine(anims);
327        };
328       
329        fxExt.flipPage = function(/*Object*/ args){
330                // summary: An extension to `dojox.fx.flip` providing a page flip like animation.
331                //
332                // description:
333                //              An extension to `dojox.fx.flip` providing a page flip effect.
334                //              Behaves the same as `dojox.fx.flip`, using the same attributes and
335                //              other standard `dojo.Animation` properties.
336                //
337                //      example:
338                //              See `dojox.fx.flip`
339                var n = args.node,
340                        coords = htmlUtil.coords(n, true),
341                        x = coords.x,
342                        y = coords.y,
343                        w = coords.w,
344                        h = coords.h,
345                        bgColor = htmlUtil.style(n, "backgroundColor"),
346                        lightColor = args.lightColor || "#dddddd",
347                        darkColor = args.darkColor,
348                        helperNode = domConstruct.create("div"),
349                        anims = [],
350                        hn = [],
351                        dir = args.dir || "right",
352                        pn = {
353                                left: ["left", "right", "x", "w"],
354                                top: ["top", "bottom", "y", "h"],
355                                right: ["left", "left", "x", "w"],
356                                bottom: ["top", "top", "y", "h"]
357                        },
358                        shiftMultiplier = {
359                                right: [1, -1],
360                                left: [-1, 1],
361                                top: [-1, 1],
362                                bottom: [1, -1]
363                        }
364                ;
365                htmlUtil.style(helperNode, {
366                        position: "absolute",
367                        width  : w + "px",
368                        height : h + "px",
369                        top        : y + "px",
370                        left   : x + "px",
371                        visibility: "hidden"
372                });
373                var hs = [];
374                for(var i = 0; i < 2; i++){
375                        var r = i % 2,
376                                d = r ? pn[dir][1] : dir,
377                                wa = r ? "last" : "first",
378                                endColor = r ? bgColor : lightColor,
379                                startColor = r ? endColor : args.startColor || n.style.backgroundColor
380                        ;
381                        hn[i] = lang.clone(helperNode);
382                        var finalize = function(x){
383                                        return function(){
384                                                domConstruct.destroy(hn[x]);
385                                        }
386                                }(i)
387                        ;
388                        winUtil.body().appendChild(hn[i]);
389                        hs[i] = {
390                                backgroundColor: r ? startColor : bgColor
391                        };
392                       
393                        hs[i][pn[dir][0]] = coords[pn[dir][2]] + shiftMultiplier[dir][0] * i * coords[pn[dir][3]] + "px";
394                        htmlUtil.style(hn[i], hs[i]);
395                        anims.push(dojox.fx.flip({
396                                node: hn[i],
397                                dir: d,
398                                axis: "shortside",
399                                depth: args.depth,
400                                duration: args.duration / 2,
401                                shift: shiftMultiplier[dir][i] * coords[pn[dir][3]] / 2,
402                                darkColor: darkColor,
403                                lightColor: lightColor,
404                                whichAnim: wa,
405                                endColor: endColor
406                        }));
407                        connectUtil.connect(anims[i], "onEnd", finalize);
408                }
409                return coreFx.chain(anims);
410        };
411       
412       
413        fxExt.flipGrid = function(/*Object*/ args){
414                // summary: An extension to `dojox.fx.flip` providing a decomposition in rows * cols flipping elements
415                //
416                // description:
417                //              An extension to `dojox.fx.flip` providing a page flip effect.
418                //              Behaves the same as `dojox.fx.flip`, using the same attributes and
419                //              other standard `dojo.Animation` properties and
420                //
421                //              cols: Integer columns
422                //              rows: Integer rows
423                //
424                //              duration: the single flip duration
425                //
426                //      example:
427                //              See `dojox.fx.flip`
428                var rows = args.rows || 4,
429                        cols = args.cols || 4,
430                        anims = [],
431                        helperNode = domConstruct.create("div"),
432                        n = args.node,
433                        coords = htmlUtil.coords(n, true),
434                        x = coords.x,
435                        y = coords.y,
436                        nw = coords.w,
437                        nh = coords.h,
438                        w = coords.w / cols,
439                        h = coords.h / rows,
440                        cAnims = []
441                ;
442                htmlUtil.style(helperNode, {
443                        position: "absolute",
444                        width: w + "px",
445                        height: h + "px",
446                        backgroundColor: htmlUtil.style(n, "backgroundColor")
447                });
448                for(var i = 0; i < rows; i++){
449                        var r = i % 2,
450                                d = r ? "right" : "left",
451                                signum = r ? 1 : -1
452                        ;
453                        // cloning
454                        var cn = lang.clone(n);
455                        htmlUtil.style(cn, {
456                                position: "absolute",
457                                width: nw + "px",
458                                height: nh + "px",
459                                top: y + "px",
460                                left: x + "px",
461                                clip: "rect(" + i * h + "px," + nw + "px," + nh + "px,0)"
462                        });
463                        winUtil.body().appendChild(cn);
464                        anims[i] = [];
465                        for(var j = 0; j < cols; j++){
466                                var hn = lang.clone(helperNode),
467                                        l = r ? j : cols - (j + 1)
468                                ;
469                                var adjustClip = function(xn, yCounter, xCounter){
470                                        return function(){
471                                                if(!(yCounter % 2)){
472                                                        htmlUtil.style(xn, {
473                                                                clip: "rect(" + yCounter * h + "px," + (nw - (xCounter + 1) * w ) + "px," + ((yCounter + 1) * h) + "px,0px)"
474                                                        });
475                                                }else{
476                                                        htmlUtil.style(xn, {
477                                                                clip: "rect(" + yCounter * h + "px," + nw + "px," + ((yCounter + 1) * h) + "px," + ((xCounter + 1) * w) + "px)"
478                                                        });
479                                                }
480                                        }
481                                }(cn, i, j);
482                                winUtil.body().appendChild(hn);
483                                htmlUtil.style(hn, {
484                                        left: x + l * w + "px",
485                                        top: y + i * h + "px",
486                                        visibility: "hidden"
487                                });
488                                var a = dojox.fx.flipPage({
489                                   node: hn,
490                                   dir: d,
491                                   duration: args.duration || 900,
492                                   shift: signum * w/2,
493                                   depth: .2,
494                                   darkColor: args.darkColor,
495                                   lightColor: args.lightColor,
496                                   startColor: args.startColor || args.node.style.backgroundColor
497                                }),
498                                removeHelper = function(xn){
499                                        return function(){
500                                                domConstruct.destroy(xn);
501                                        }
502                                }(hn)
503                                ;
504                                connectUtil.connect(a, "play", this, adjustClip);
505                                connectUtil.connect(a, "play", this, removeHelper);
506                                anims[i].push(a);
507                        }
508                        cAnims.push(coreFx.chain(anims[i]));
509                       
510                }
511                connectUtil.connect(cAnims[0], "play", function(){
512                        htmlUtil.style(n, {visibility: "hidden"});
513                });
514                return coreFx.combine(cAnims);
515        };
516        return fxExt;
517});
Note: See TracBrowser for help on using the repository browser.