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