1 | define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin", "dojo/fx/easing"], function(dojo, dijit, dojox){ |
---|
2 | |
---|
3 | dojo.experimental("dojox.image.Badge"); |
---|
4 | dojo.getObject("image", true, dojox); |
---|
5 | |
---|
6 | dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._TemplatedMixin], { |
---|
7 | // summary: A simple grid of Images that loops through thumbnails |
---|
8 | // |
---|
9 | |
---|
10 | baseClass: "dojoxBadge", |
---|
11 | |
---|
12 | templateString:'<div class="dojoxBadge" dojoAttachPoint="containerNode"></div>', |
---|
13 | |
---|
14 | // children: String |
---|
15 | // A CSS3 Selector that determines the node to become a child |
---|
16 | children: "div.dojoxBadgeImage", |
---|
17 | |
---|
18 | // rows: Integer |
---|
19 | // Number of Rows to display |
---|
20 | rows: 4, |
---|
21 | |
---|
22 | // cols: Integer |
---|
23 | // Number of Columns to display |
---|
24 | cols: 5, |
---|
25 | |
---|
26 | // cellSize: Integer |
---|
27 | // Size in PX of each thumbnail |
---|
28 | cellSize: 50, |
---|
29 | |
---|
30 | // cellMargin: Integer |
---|
31 | // Size in PX to adjust for cell margins |
---|
32 | cellMargin: 1, |
---|
33 | |
---|
34 | // delay: Integer |
---|
35 | // Time (in ms) to show the image before sizing down again |
---|
36 | delay: 2000, |
---|
37 | |
---|
38 | // threads: Integer |
---|
39 | // how many cycles will be going "simultaneously" (>2 not reccommended) |
---|
40 | threads: 1, |
---|
41 | |
---|
42 | // easing: Function|String |
---|
43 | // An easing function to use when showing the node (does not apply to shrinking) |
---|
44 | easing: "dojo.fx.easing.backOut", |
---|
45 | |
---|
46 | startup: function(){ |
---|
47 | if(this._started){ return; } |
---|
48 | if(dojo.isString(this.easing)){ |
---|
49 | this.easing = dojo.getObject(this.easing); |
---|
50 | } |
---|
51 | this.inherited(arguments); |
---|
52 | this._init(); |
---|
53 | }, |
---|
54 | |
---|
55 | _init: function(){ |
---|
56 | // summary: Setup and layout the images |
---|
57 | |
---|
58 | var _row = 0, |
---|
59 | _w = this.cellSize; |
---|
60 | |
---|
61 | dojo.style(this.domNode, { |
---|
62 | width: _w * this.cols + "px", |
---|
63 | height: _w * this.rows + "px" |
---|
64 | }); |
---|
65 | |
---|
66 | this._nl = dojo.query(this.children, this.containerNode) |
---|
67 | .forEach(function(n, _idx){ |
---|
68 | |
---|
69 | var _col = _idx % this.cols, |
---|
70 | t = _row * _w, |
---|
71 | l = _col * _w, |
---|
72 | m = this.cellMargin * 2; |
---|
73 | |
---|
74 | dojo.style(n, { |
---|
75 | top: t + "px", |
---|
76 | left: l + "px", |
---|
77 | width: _w - m + "px", |
---|
78 | height: _w - m + "px" |
---|
79 | }); |
---|
80 | |
---|
81 | if(_col == this.cols - 1){ _row++; } |
---|
82 | dojo.addClass(n, this.baseClass + "Image"); |
---|
83 | |
---|
84 | }, this) |
---|
85 | ; |
---|
86 | |
---|
87 | var l = this._nl.length; |
---|
88 | while(this.threads--){ |
---|
89 | var s = Math.floor(Math.random() * l); |
---|
90 | setTimeout(dojo.hitch(this, "_enbiggen", { |
---|
91 | target: this._nl[s] |
---|
92 | }), this.delay * this.threads); |
---|
93 | } |
---|
94 | |
---|
95 | }, |
---|
96 | |
---|
97 | _getCell: function(/* DomNode */ n){ |
---|
98 | // summary: Return information about the position for a given node |
---|
99 | var _pos = this._nl.indexOf(n); |
---|
100 | if(_pos >= 0){ |
---|
101 | var _col = _pos % this.cols; |
---|
102 | var _row = Math.floor(_pos / this.cols); |
---|
103 | return { x: _col, y: _row, n: this._nl[_pos], io: _pos }; |
---|
104 | }else{ |
---|
105 | return undefined; |
---|
106 | } |
---|
107 | }, |
---|
108 | |
---|
109 | _getImage: function(){ |
---|
110 | // summary: Returns the next image in the list, or the first one if not available |
---|
111 | return "url('')"; |
---|
112 | }, |
---|
113 | |
---|
114 | _enbiggen: function(/* Event|DomNode */ e){ |
---|
115 | // summary: Show the passed node in the picker |
---|
116 | var _pos = this._getCell(e.target || e); |
---|
117 | |
---|
118 | if (_pos){ |
---|
119 | // we have a node, and know where it is |
---|
120 | |
---|
121 | var m = this.cellMargin, |
---|
122 | _cc = (this.cellSize * 2) - (m * 2), |
---|
123 | props = { |
---|
124 | height: _cc, |
---|
125 | width: _cc |
---|
126 | } |
---|
127 | ; |
---|
128 | |
---|
129 | var _tehDecider = function(){ |
---|
130 | // if we have room, we'll want to decide which direction to go |
---|
131 | // let "teh decider" decide. |
---|
132 | return Math.round(Math.random()); |
---|
133 | }; |
---|
134 | |
---|
135 | if(_pos.x == this.cols - 1 || (_pos.x > 0 && _tehDecider() )){ |
---|
136 | // we have to go left, at right edge (or we want to and not on left edge) |
---|
137 | props.left = this.cellSize * (_pos.x - m); |
---|
138 | } |
---|
139 | |
---|
140 | if(_pos.y == this.rows - 1 || (_pos.y > 0 && _tehDecider() )){ |
---|
141 | // we have to go up, at bottom edge (or we want to and not at top) |
---|
142 | props.top = this.cellSize * (_pos.y - m); |
---|
143 | } |
---|
144 | |
---|
145 | var bc = this.baseClass; |
---|
146 | dojo.addClass(_pos.n, bc + "Top"); |
---|
147 | dojo.addClass(_pos.n, bc + "Seen"); |
---|
148 | |
---|
149 | dojo.animateProperty({ node: _pos.n, properties: props, |
---|
150 | onEnd: dojo.hitch(this, "_loadUnder", _pos, props), |
---|
151 | easing: this.easing |
---|
152 | }).play(); |
---|
153 | |
---|
154 | } |
---|
155 | }, |
---|
156 | |
---|
157 | _loadUnder: function(info, props){ |
---|
158 | // summary: figure out which three images are being covered, and |
---|
159 | // determine if they need loaded or not |
---|
160 | |
---|
161 | var idx = info.io; |
---|
162 | var nodes = []; |
---|
163 | |
---|
164 | var isLeft = (props.left >= 0); |
---|
165 | var isUp = (props.top >= 0); |
---|
166 | |
---|
167 | var c = this.cols, |
---|
168 | // the three node index's we're allegedly over: |
---|
169 | e = idx + (isLeft ? -1 : 1), |
---|
170 | f = idx + (isUp ? -c : c), |
---|
171 | // don't ask: |
---|
172 | g = (isUp ? (isLeft ? e - c : f + 1) : (isLeft ? f - 1 : e + c)), |
---|
173 | |
---|
174 | bc = this.baseClass; |
---|
175 | |
---|
176 | dojo.forEach([e, f, g], function(x){ |
---|
177 | var n = this._nl[x]; |
---|
178 | if(n){ |
---|
179 | if(dojo.hasClass(n, bc + "Seen")){ |
---|
180 | // change the background image out? |
---|
181 | dojo.removeClass(n, bc + "Seen"); |
---|
182 | } |
---|
183 | } |
---|
184 | },this); |
---|
185 | |
---|
186 | setTimeout(dojo.hitch(this, "_disenbiggen", info, props), this.delay * 1.25); |
---|
187 | |
---|
188 | }, |
---|
189 | |
---|
190 | _disenbiggen: function(info, props){ |
---|
191 | // summary: Hide the passed node (info.n), passing along properties |
---|
192 | // received. |
---|
193 | |
---|
194 | if(props.top >= 0){ |
---|
195 | props.top += this.cellSize; |
---|
196 | } |
---|
197 | if(props.left >= 0){ |
---|
198 | props.left += this.cellSize; |
---|
199 | } |
---|
200 | var _cc = this.cellSize - (this.cellMargin * 2); |
---|
201 | dojo.animateProperty({ |
---|
202 | node: info.n, |
---|
203 | properties: dojo.mixin(props, { |
---|
204 | width:_cc, |
---|
205 | height:_cc |
---|
206 | }), |
---|
207 | onEnd: dojo.hitch(this, "_cycle", info, props) |
---|
208 | }).play(5); |
---|
209 | }, |
---|
210 | |
---|
211 | _cycle: function(info, props){ |
---|
212 | // summary: Select an un-viewed image from the list, and show it |
---|
213 | |
---|
214 | var bc = this.baseClass; |
---|
215 | dojo.removeClass(info.n, bc + "Top"); |
---|
216 | var ns = this._nl.filter(function(n){ |
---|
217 | return !dojo.hasClass(n, bc + "Seen") |
---|
218 | }); |
---|
219 | var c = ns[Math.floor(Math.random() * ns.length)]; |
---|
220 | setTimeout(dojo.hitch(this,"_enbiggen", { target: c }), this.delay / 2) |
---|
221 | |
---|
222 | } |
---|
223 | |
---|
224 | }); |
---|
225 | |
---|
226 | return dojox.image.Badge; |
---|
227 | }) |
---|
228 | |
---|