source: Dev/trunk/src/client/dojox/fx/flip.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

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