1 | define([ |
---|
2 | "dojo/_base/array", |
---|
3 | "dojo/_base/connect", |
---|
4 | "dojo/_base/lang", |
---|
5 | "dojo/dom-style", |
---|
6 | "dojo/_base/fx", |
---|
7 | "dojo/fx" |
---|
8 | ], function(array, connect, lang, domStyle, baseFx, fx) { |
---|
9 | |
---|
10 | // Constants used to identify which edge the pane pans in from. |
---|
11 | var DOWN = 0, |
---|
12 | RIGHT = 1, |
---|
13 | UP = 2, |
---|
14 | LEFT = 3; |
---|
15 | |
---|
16 | function _pan(/*int*/type, /*Object*/args){ |
---|
17 | // summary: |
---|
18 | // Handles the preparation of the dom node and creates the dojo.Animation object. |
---|
19 | var n = args.next.node, |
---|
20 | r = args.rotatorBox, |
---|
21 | m = type % 2, |
---|
22 | a = m ? "left" : "top", |
---|
23 | s = (m ? r.w : r.h) * (type < 2 ? -1 : 1), |
---|
24 | p = {}, |
---|
25 | q = {}; |
---|
26 | |
---|
27 | domStyle.set(n, "display", ""); |
---|
28 | |
---|
29 | p[a] = { |
---|
30 | start: 0, |
---|
31 | end: -s |
---|
32 | }; |
---|
33 | |
---|
34 | q[a] = { |
---|
35 | start: s, |
---|
36 | end: 0 |
---|
37 | }; |
---|
38 | |
---|
39 | return fx.combine([ /*dojo.Animation*/ |
---|
40 | baseFx.animateProperty({ |
---|
41 | node: args.current.node, |
---|
42 | duration: args.duration, |
---|
43 | properties: p, |
---|
44 | easing: args.easing |
---|
45 | }), |
---|
46 | baseFx.animateProperty({ |
---|
47 | node: n, |
---|
48 | duration: args.duration, |
---|
49 | properties: q, |
---|
50 | easing: args.easing |
---|
51 | }) |
---|
52 | ]); |
---|
53 | } |
---|
54 | |
---|
55 | function _setZindex(/*DomNode*/n, /*int*/z){ |
---|
56 | // summary: |
---|
57 | // Helper function for continuously panning. |
---|
58 | domStyle.set(n, "zIndex", z); |
---|
59 | } |
---|
60 | |
---|
61 | var exports = { |
---|
62 | pan: function(/*Object*/args){ |
---|
63 | // summary: |
---|
64 | // Returns a dojo.Animation that either pans left or right to the next pane. |
---|
65 | // The actual direction depends on the order of the panes. |
---|
66 | // |
---|
67 | // If panning forward from index 1 to 3, it will perform a pan left. If panning |
---|
68 | // backwards from 5 to 1, then it will perform a pan right. |
---|
69 | // |
---|
70 | // If the parameter "continuous" is set to true, it will return an animation |
---|
71 | // chain of several pan animations of each intermediate pane panning. For |
---|
72 | // example, if you pan forward from 1 to 3, it will return an animation panning |
---|
73 | // left from 1 to 2 and then 2 to 3. |
---|
74 | // |
---|
75 | // If an easing is specified, it will be applied to each pan transition. For |
---|
76 | // example, if you are panning from pane 1 to pane 5 and you set the easing to |
---|
77 | // "dojo.fx.easing.elasticInOut", then it will "wobble" 5 times, once for each |
---|
78 | // pan transition. |
---|
79 | // |
---|
80 | // If the parameter "wrap" is set to true, it will pan to the next pane using |
---|
81 | // the shortest distance in the array of panes. For example, if there are 6 |
---|
82 | // panes, then panning from 5 to 1 will pan forward (left) from pane 5 to 6 and |
---|
83 | // 6 to 1. If the distance is the same either going forward or backwards, then |
---|
84 | // it will always pan forward (left). |
---|
85 | // |
---|
86 | // A continuous pan will use the target pane's duration to pan all intermediate |
---|
87 | // panes. To use the target's pane duration for each intermediate pane, then |
---|
88 | // set the "quick" parameter to "false". |
---|
89 | |
---|
90 | var w = args.wrap, |
---|
91 | p = args.rotator.panes, |
---|
92 | len = p.length, |
---|
93 | z = len, |
---|
94 | j = args.current.idx, |
---|
95 | k = args.next.idx, |
---|
96 | nw = Math.abs(k - j), |
---|
97 | ww = Math.abs((len - Math.max(j, k)) + Math.min(j, k)) % len, |
---|
98 | _forward = j < k, |
---|
99 | _dir = LEFT, |
---|
100 | _pans = [], |
---|
101 | _nodes = [], |
---|
102 | _duration = args.duration; |
---|
103 | |
---|
104 | // default to pan left, but check if we should pan right. |
---|
105 | // need to take into account wrapping. |
---|
106 | if((!w && !_forward) || (w && (_forward && nw > ww || !_forward && nw < ww))){ |
---|
107 | _dir = RIGHT; |
---|
108 | } |
---|
109 | |
---|
110 | if(args.continuous){ |
---|
111 | // if continuous pans are quick, then divide the duration by the number of panes |
---|
112 | if(args.quick){ |
---|
113 | _duration = Math.round(_duration / (w ? Math.min(ww, nw) : nw)); |
---|
114 | } |
---|
115 | |
---|
116 | // set the current pane's z-index |
---|
117 | _setZindex(p[j].node, z--); |
---|
118 | |
---|
119 | var f = (_dir == LEFT); |
---|
120 | |
---|
121 | // loop and set z-indexes and get all pan animations |
---|
122 | while(1){ |
---|
123 | // set the current pane |
---|
124 | var i = j; |
---|
125 | |
---|
126 | // increment/decrement the next pane's index |
---|
127 | if(f){ |
---|
128 | if(++j >= len){ |
---|
129 | j = 0; |
---|
130 | } |
---|
131 | }else{ |
---|
132 | if(--j < 0){ |
---|
133 | j = len - 1; |
---|
134 | } |
---|
135 | } |
---|
136 | |
---|
137 | var x = p[i], |
---|
138 | y = p[j]; |
---|
139 | |
---|
140 | // set next pane's z-index |
---|
141 | _setZindex(y.node, z--); |
---|
142 | |
---|
143 | // build the pan animation |
---|
144 | _pans.push(_pan(_dir, lang.mixin({ |
---|
145 | easing: function(m){ return m; } // continuous gets a linear easing by default |
---|
146 | }, args, { |
---|
147 | current: x, |
---|
148 | next: y, |
---|
149 | duration: _duration |
---|
150 | }))); |
---|
151 | |
---|
152 | // if we're done, then break out of the loop |
---|
153 | if((f && j == k) || (!f && j == k)){ |
---|
154 | break; |
---|
155 | } |
---|
156 | |
---|
157 | // this must come after the break... we don't want the last pane to get it's |
---|
158 | // styles reset. |
---|
159 | _nodes.push(y.node); |
---|
160 | } |
---|
161 | |
---|
162 | // build the chained animation of all pan animations |
---|
163 | var _anim = fx.chain(_pans), |
---|
164 | |
---|
165 | // clean up styles when the chained animation finishes |
---|
166 | h = connect.connect(_anim, "onEnd", function(){ |
---|
167 | connect.disconnect(h); |
---|
168 | array.forEach(_nodes, function(q){ |
---|
169 | domStyle.set(q, { |
---|
170 | display: "none", |
---|
171 | left: 0, |
---|
172 | opacity: 1, |
---|
173 | top: 0, |
---|
174 | zIndex: 0 |
---|
175 | }); |
---|
176 | }); |
---|
177 | }); |
---|
178 | |
---|
179 | return _anim; |
---|
180 | } |
---|
181 | |
---|
182 | // we're not continuous, so just return a normal pan animation |
---|
183 | return _pan(_dir, args); /*dojo.Animation*/ |
---|
184 | }, |
---|
185 | |
---|
186 | panDown: function(/*Object*/args){ |
---|
187 | // summary: |
---|
188 | // Returns a dojo.Animation that pans in the next rotator pane from the top. |
---|
189 | return _pan(DOWN, args); /*dojo.Animation*/ |
---|
190 | }, |
---|
191 | |
---|
192 | panRight: function(/*Object*/args){ |
---|
193 | // summary: |
---|
194 | // Returns a dojo.Animation that pans in the next rotator pane from the right. |
---|
195 | return _pan(RIGHT, args); /*dojo.Animation*/ |
---|
196 | }, |
---|
197 | |
---|
198 | panUp: function(/*Object*/args){ |
---|
199 | // summary: |
---|
200 | // Returns a dojo.Animation that pans in the next rotator pane from the bottom. |
---|
201 | return _pan(UP, args); /*dojo.Animation*/ |
---|
202 | }, |
---|
203 | |
---|
204 | panLeft: function(/*Object*/args){ |
---|
205 | // summary: |
---|
206 | // Returns a dojo.Animation that pans in the next rotator pane from the left. |
---|
207 | return _pan(LEFT, args); /*dojo.Animation*/ |
---|
208 | } |
---|
209 | }; |
---|
210 | |
---|
211 | // back-compat, remove for 2.0 |
---|
212 | lang.mixin(lang.getObject("dojox.widget.rotator"), exports); |
---|
213 | |
---|
214 | return exports; |
---|
215 | }); |
---|