ux/FlipCounter.js
[roojs1] / ux / FlipCounter.js
1
2
3 Roo.ux.FlipCounter = function(options)
4 {
5     Roo.ux.FlipCounter.superclass.constructor.call(this, options);
6     
7     //Roo.apply(this, options);
8     //this.el = $(element);
9     //this.options = $.extend({}, defaults, options);
10     this.addEvents({
11         // raw events
12         /**
13          * @event flip
14          * When a box is flipped
15          * @param {Roo.ux.FlipCounter} counter
16          */
17         "flip" : true,
18         /**
19          * @event resize
20          * When a box is resized
21          * @param {Roo.ux.FlipCounter} counter
22          */
23         "resize" : true
24         
25          
26     });
27     this.digits = new Array();
28        
29     //this.init();
30
31
32     
33 }
34 Roo.extend(Roo.ux.FlipCounter, Roo.bootstrap.Component, {
35     
36     speed : 0.2,
37     startnumber : 0,
38     currentNumber : 0,
39     decimal : 0,
40     
41     digits : false, // array...
42     ulWidth : 0,
43     cls : '',
44     
45     getAutoCreate : function(){
46         
47         return {
48             tag: 'ul',
49             cls: 'flipcounter ' + this.cls,
50             
51         };
52     },
53         
54     initEvents : function ()
55     { 
56         var startNum = (1.0*this.startnumber).toFixed(this.decimal);
57         
58         for (i=startNum.length-1; i>=0; i=i-1)
59         {
60             if (startNum[i] == '.') {
61                 this.addSeparator('.');
62                 continue;
63             }
64             this.addDigit(startNum[i]);
65         }
66         this.currentNumber = this.startnumber;
67     },
68     
69     addDigit : function (num)
70     {
71         // Add separator after every 3rd digit
72         /*if (this.digits.length % 3 == 0 && this.digits.length != 0)
73         {
74             this.addSeparator(',');
75         }
76         */
77           
78         
79         var digit = new Roo.ux.FlipCounter.Digit({ manager : this, currentNumber : num });
80         digit.manager = this;
81         this.digits.push(digit);
82         digit.render(this.el, 0);
83          
84         // Update width
85         this.ulWidth = this.ulWidth + digit.el.getWidth(true);
86         this.el.set({
87             'min-width' : this.ulWidth,
88             'min-height' :digit.el.getHeight(true)
89         });
90         
91     },
92     
93     removeDigit : function ()
94     {
95         var digit = this.digits.splice(this.digits.length-1, 1)[0];
96         
97         this.ulWidth = this.ulWidth - digit.el.getWidth(true);
98         digit.el.remove();
99         
100         // Remove separators
101        // if (this.digits.length % 3 == 0)
102       //  {
103           //  var comma = this.el.select('li.comma:first-child');
104           //  this.ulWidth = this.ulWidth - comma.getWidth(true);
105           //  comma.remove();
106         //}
107         
108         // Update width to current
109         this.el.set( { 'min-width' : this.ulWidth});
110     },
111     
112     addSeparator : function (str)
113     {
114         var comma = this.el.insertHtml('afterBegin','<li class="comma">'+str+'</li>',true);
115         
116         // Update width
117         
118         this.ulWidth = this.ulWidth + comma.getWidth(true);
119         this.el.set({'min-width' : this.ulWidth});
120     },
121     
122     updateTo : function (num)
123     {
124         var numStr = (1.0*num).toFixed(this.decimal);
125         
126         this.currentNumber = num;
127         
128         var dl = this.digits.length + (this.decimal > 0 ? 1 : 0);
129         // Change the number of digits displayed if needed
130         if (numStr.length != dl)
131         {
132             var diff = numStr.length - dl;
133             Roo.log("DIFF LEN=" +diff);
134             if (diff > 0)
135             {
136                 for (i=0; i<diff; i=i+1) {
137                     this.addDigit(0);
138                 }
139             }
140             else
141             {
142                 for (i=diff; i<0; i=i+1) {
143                     this.removeDigit();
144                 }
145             }
146             
147             this.fireEvent('onResize',this);
148         }
149         
150         // Change all digit values
151         
152         for (i=0, n=0; i<numStr.length; i=i+1)
153         {
154             if (numStr[numStr.length - 1 - i] == '.') {
155                 continue;
156             }
157             Roo.log("UPDATE DIGIT=" + i + " to " + numStr[numStr.length - 1 - i]);
158             this.digits[n++].flipTo(numStr[numStr.length - 1 - i]);
159         }
160     }
161     
162 });
163
164 Roo.ux.FlipCounter.Digit = function(options)
165 {
166     //Roo.apply(this, options);
167     Roo.ux.FlipCounter.Digit.superclass.constructor.call(this, options);
168
169     
170     this.currentNumber = parseInt(this.currentNumber);
171     
172     
173 }
174
175 Roo.extend(Roo.ux.FlipCounter.Digit, Roo.bootstrap.Component, {
176
177     manager : null, // the flipcounter... 
178     currentNumber : 0,
179     
180     
181     currentNum : 0,
182     nextNum : 0,
183     targetNum : 0,
184     
185     topFrontDiv  : null,
186     bottomFrontDiv : null,
187     topNumBack : null,
188     topNumFront : null,
189     bottomNumBack : null,
190     bottomNumFront : null,
191     
192     
193     
194     
195     getAutoCreate : function(){
196         
197         return {
198                 tag: 'li',
199                 cn : [
200                     {
201                         cls: 'numberwrap',
202                         cn : [
203                             { cls : 'flipper_top flipper_top1' },
204                             {
205                                 cls : 'flipper_top flipper_top2 flipper_top_back',
206                                 cn : [
207                                     { tag: 'span', html: this.currentNumber },
208                                     { cls : 'rings' }
209                                 ]
210                         
211                             },
212                             {
213                                 cls : 'flipper_top flipper_top_front',
214                                 cn : [
215                                     { tag: 'span', html: this.currentNumber },
216                                     { cls : 'rings' }
217                                 ]
218                         
219                             },
220                             { cls : 'flipper_bottom flipper_bottom4' },
221                             { cls : 'flipper_bottom flipper_bottom3' },
222                             { cls : 'flipper_bottom flipper_bottom2' },
223                             {
224                                 cls : 'flipper_bottom flipper_bottom1 flipper_bottom_back',
225                                 cn : [
226                                     { tag: 'span', html: this.currentNumber },
227                                     { cls : 'rings' }
228                                 ]
229                             },
230                             {
231                                 cls : 'flipper_bottom flipper_bottom_front',
232                                 cn : [
233                                     { tag: 'span', html: this.currentNumber },
234                                     { cls : 'rings' }
235                                 ]
236                             },
237                         ]
238                     }
239                 ]
240         };
241     },
242     
243     
244     initEvents : function()
245     {
246         
247          
248         
249         this.topFrontDiv = this.el.select('.flipper_top_front',true).first();
250         this.bottomFrontDiv = this.el.select('.flipper_bottom_front',true).first();
251         this.topNumBack = this.el.select('.flipper_top_back span',true).first();
252         this.topNumFront = this.el.select('.flipper_top_front span',true).first();
253         this.bottomNumBack = this.el.select('.flipper_bottom_back span',true).first();
254         this.bottomNumFront = this.el.select('.flipper_bottom_front span',true).first();
255         
256         this.targetNum = this.currentNumber;
257         this.currentNum = this.currentNumber;
258         this.nextNum = this.currentNumber;
259         
260         this.currentlyAnimating = false;
261     },
262     
263     flipTo : function (num)
264     {
265         if (this.currentNum === num)
266             return;
267         
268         this.targetNum = num;
269         if (this.currentlyAnimating) {
270             return;
271         }
272         
273         this.animNext();
274     },
275     
276     animNext : function ()
277     {
278         if (this.currentNum == this.targetNum)
279         {
280             this.currentlyAnimating = false;
281             return;
282         }
283         
284         var doRandomDelay = !this.currentlyAnimating;
285         this.currentlyAnimating = true;
286         this.nextNum = this.currentNum + 1;
287         if (this.nextNum > 9) {
288             this.nextNum = 0;
289         }
290         
291         var delay = Math.random()/5;
292         if (!doRandomDelay) {
293             delay = 0.01;
294         }
295         
296         // Animate top flipper
297         var digit = this;
298         digit.topNumBack.dom.innerHTML = digit.nextNum;
299         (function() {
300             digit.topFrontDiv.animate(
301                 {
302                     scaleY: {from :1, to : 0}
303                 },
304                 this.manager.speed, //duration
305                 function() {}, // oncomplate
306                 'easeIn', //easing,
307                 'motion' // desplay type.
308             );
309         }).defer(delay, this);
310         
311         (function() {
312             
313             digit.bottomNumFront.dom.innerHTML  = digit.nextNum;
314             
315             digit.bottomFrontDiv.animate(
316                 {
317                     scaleY: {from: 0, to : 1},
318                     
319                 },
320                 this.manager.speed * 0.5, //duration
321                 function() {
322                     digit.currentNum = digit.nextNum;
323                     digit.topNumFront.dom.innerHTML = digit.currentNum;
324                     digit.topFrontDiv.attr('style', '');
325                     digit.bottomNumBack.dom.innerHTML = digit.currentNum;
326                     
327                     digit.animNext();
328                     digit.manager.fireEvent('onFlip', digit.manager);
329                     
330                  }, // oncomplate
331                 'easeOut', //easing,
332                 'motion' // desplay type.
333             )
334             
335         }).defer(delay + this.manager.speed, this);
336                 
337                 
338  
339        //??? digit.bottomFrontDiv. digit.bottomNumFront.html(digit.nextNum);
340         
341        
342     }
343 });