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