| 1 | (function($) {
 | 
| 2 |   var Roulette = function(options) {
 | 
| 3 |     var defaultSettings = {
 | 
| 4 |       maxPlayCount : null, // x >= 0 or null
 | 
| 5 |       speed : 15, // x > 0
 | 
| 6 |       stopImageNumber : null, // x >= 0 or null or -1
 | 
| 7 |       rollCount : 3, // x >= 0
 | 
| 8 |       duration : 2, //(x second)  
 | 
| 9 |       stopCallback : function() {
 | 
| 10 |       },
 | 
| 11 |       startCallback : function() {
 | 
| 12 |       },
 | 
| 13 |       slowDownCallback : function() {
 | 
| 14 |       }
 | 
| 15 |     }
 | 
| 16 |     var defaultProperty = {
 | 
| 17 |       playCount : 0,
 | 
| 18 |       $rouletteTarget : null,
 | 
| 19 |       imageCount : null,
 | 
| 20 |       $images : null,
 | 
| 21 |       originalStopImageNumber : null,
 | 
| 22 |       totalHeight : null,
 | 
| 23 |       topPosition : 0,
 | 
| 24 | 
 | 
| 25 |       maxDistance : null,
 | 
| 26 |       slowDownStartDistance : null,
 | 
| 27 | 
 | 
| 28 |       isRunUp : true,
 | 
| 29 |       isSlowdown : false,
 | 
| 30 |       isStop : false,
 | 
| 31 | 
 | 
| 32 |       distance : 0,
 | 
| 33 |       runUpDistance : null,
 | 
| 34 |       isIE : navigator.userAgent.toLowerCase().indexOf('msie') > -1 // TODO IE
 | 
| 35 |     };
 | 
| 36 |     var p = $.extend({}, defaultSettings, options, defaultProperty);
 | 
| 37 | 
 | 
| 38 |     var reset = function() {
 | 
| 39 |       p.maxDistance = defaultProperty.maxDistance;
 | 
| 40 |       p.slowDownStartDistance = defaultProperty.slowDownStartDistance;
 | 
| 41 |       p.distance = defaultProperty.distance;
 | 
| 42 |       p.isRunUp = defaultProperty.isRunUp;
 | 
| 43 |       p.isSlowdown = defaultProperty.isSlowdown;
 | 
| 44 |       p.isStop = defaultProperty.isStop;
 | 
| 45 |       p.topPosition = defaultProperty.topPosition;
 | 
| 46 |     }
 | 
| 47 |     
 | 
| 48 |     var slowDownSetup = function() {
 | 
| 49 |       if(p.isSlowdown){
 | 
| 50 |         return;
 | 
| 51 |       }
 | 
| 52 |       p.slowDownCallback();
 | 
| 53 |       p.isSlowdown = true;
 | 
| 54 |       p.slowDownStartDistance = p.distance;
 | 
| 55 |       p.maxDistance = p.distance + (2*p.totalHeight);
 | 
| 56 |       p.maxDistance += p.imageHeight - p.topPosition % p.imageHeight;
 | 
| 57 |       if (p.stopImageNumber != null) {
 | 
| 58 |         p.maxDistance += (p.totalHeight - (p.maxDistance % p.totalHeight) + (p.stopImageNumber * p.imageHeight))
 | 
| 59 |             % p.totalHeight;
 | 
| 60 |       }
 | 
| 61 |     }
 | 
| 62 | 
 | 
| 63 |     var roll = function() {
 | 
| 64 |       var speed_ = p.speed;
 | 
| 65 | 
 | 
| 66 |       if (p.isRunUp) {
 | 
| 67 |         if (p.distance <= p.runUpDistance) {
 | 
| 68 |           var rate_ = ~~((p.distance / p.runUpDistance) * p.speed);
 | 
| 69 |           speed_ = rate_ + 1;
 | 
| 70 |         } else {
 | 
| 71 |           p.isRunUp = false;
 | 
| 72 |         }
 | 
| 73 | 
 | 
| 74 |       } else if (p.isSlowdown) {
 | 
| 75 |         var rate_ = ~~(((p.maxDistance - p.distance) / (p.maxDistance - p.slowDownStartDistance)) * (p.speed));
 | 
| 76 |         speed_ = rate_ + 1;
 | 
| 77 |       }
 | 
| 78 | 
 | 
| 79 |       if (p.maxDistance && p.distance >= p.maxDistance) {
 | 
| 80 |         p.isStop = true;
 | 
| 81 |         reset();
 | 
| 82 |         p.stopCallback(p.$rouletteTarget.find('img').eq(p.stopImageNumber));
 | 
| 83 |         return;
 | 
| 84 |       }
 | 
| 85 |       p.distance += speed_;
 | 
| 86 |       p.topPosition += speed_;
 | 
| 87 |       if (p.topPosition >= p.totalHeight) {
 | 
| 88 |         p.topPosition = p.topPosition - p.totalHeight;
 | 
| 89 |       }
 | 
| 90 |       // TODO IE 
 | 
| 91 |       if (p.isIE) {
 | 
| 92 |         p.$rouletteTarget.css('top', '-' + p.topPosition + 'px');
 | 
| 93 |       } else {
 | 
| 94 |         // TODO more smooth roll
 | 
| 95 |         p.$rouletteTarget.css('transform', 'translate(-' + p.topPosition + 'px,0px)'); // einfach die positionen vom transform getauscht.
 | 
| 96 | //ORIGINAL p.$rouletteTarget.css('transform', 'translate(0px, -' + p.topPosition + 'px)');
 | 
| 97 |       }
 | 
| 98 |       setTimeout(roll, 1);
 | 
| 99 |     }
 | 
| 100 | 
 | 
| 101 |     var init = function($roulette) {
 | 
| 102 |       $roulette.css({ 'overflow' : 'hidden' });
 | 
| 103 |       defaultProperty.originalStopImageNumber = p.stopImageNumber;
 | 
| 104 |       if (!p.$images) {
 | 
| 105 |         p.$images = $roulette.find('img').remove();
 | 
| 106 |         p.imageCount = p.$images.length;
 | 
| 107 |         p.$images.eq(0).bind('load',function(){
 | 
| 108 |           p.imageHeight = $(this).height();
 | 
| 109 |           $roulette.css({ 'height' : (p.imageHeight + 'px') });
 | 
| 110 |           p.totalHeight = p.imageCount * p.imageHeight;
 | 
| 111 |           p.runUpDistance = 2 * p.imageHeight;
 | 
| 112 |         }).each(function(){
 | 
| 113 |           if (this.complete || this.complete === undefined){
 | 
| 114 |             var src = this.src;
 | 
| 115 |             // set BLANK image
 | 
| 116 |             this.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
 | 
| 117 |             this.src = src;
 | 
| 118 |           }  
 | 
| 119 |         });
 | 
| 120 |       }
 | 
| 121 |       $roulette.find('div').remove();
 | 
| 122 |       p.$images.css({
 | 
| 123 |         'display' : 'block'
 | 
| 124 |       });
 | 
| 125 |       p.$rouletteTarget = $('<div>').css({
 | 
| 126 |         'position' : 'relative',
 | 
| 127 |         'top' : '0'
 | 
| 128 |       }).attr('class',"roulette-inner");
 | 
| 129 |       $roulette.append(p.$rouletteTarget);
 | 
| 130 |       p.$rouletteTarget.append(p.$images);
 | 
| 131 |       p.$rouletteTarget.append(p.$images.eq(0).clone());
 | 
| 132 |       $roulette.show();
 | 
| 133 |     }
 | 
| 134 | 
 | 
| 135 |     var start = function() {
 | 
| 136 |       p.playCount++;
 | 
| 137 |       if (p.maxPlayCount && p.playCount > p.maxPlayCount) {
 | 
| 138 |         return;
 | 
| 139 |       }
 | 
| 140 |       p.stopImageNumber = $.isNumeric(defaultProperty.originalStopImageNumber) && Number(defaultProperty.originalStopImageNumber) >= 0 ?
 | 
| 141 |                   Number(defaultProperty.originalStopImageNumber) : Math.floor(Math.random() * p.imageCount); 
 | 
| 142 |       p.startCallback();
 | 
| 143 |       roll();
 | 
| 144 |       setTimeout(function(){
 | 
| 145 |         slowDownSetup();
 | 
| 146 |       }, p.duration * 1000);
 | 
| 147 |     }
 | 
| 148 | 
 | 
| 149 |     var stop = function(option) {
 | 
| 150 |       if (!p.isSlowdown) {
 | 
| 151 |         if (option) {
 | 
| 152 |           var stopImageNumber = Number(option.stopImageNumber);
 | 
| 153 |           if (0 <= stopImageNumber && stopImageNumber <= (p.imageCount - 1)) {
 | 
| 154 |             p.stopImageNumber = option.stopImageNumber;
 | 
| 155 |           }
 | 
| 156 |         }
 | 
| 157 |         slowDownSetup();
 | 
| 158 |       }
 | 
| 159 |     }
 | 
| 160 |     var option = function(options) {
 | 
| 161 |       p = $.extend(p, options);
 | 
| 162 |       p.speed = Number(p.speed);
 | 
| 163 |       p.duration = Number(p.duration);
 | 
| 164 |       p.duration = p.duration > 1 ? p.duration - 1 : 1; 
 | 
| 165 |       defaultProperty.originalStopImageNumber = options.stopImageNumber; 
 | 
| 166 |     }
 | 
| 167 | 
 | 
| 168 |     var ret = {
 | 
| 169 |       start : start,
 | 
| 170 |       stop : stop,
 | 
| 171 |       init : init,
 | 
| 172 |       option : option
 | 
| 173 |     }
 | 
| 174 |     return ret;
 | 
| 175 |   }
 | 
| 176 | 
 | 
| 177 |   var pluginName = 'roulette';
 | 
| 178 |   $.fn[pluginName] = function(method, options) {
 | 
| 179 |     return this.each(function() {
 | 
| 180 |       var self = $(this);
 | 
| 181 |       var roulette = self.data('plugin_' + pluginName);
 | 
| 182 | 
 | 
| 183 |       if (roulette) {
 | 
| 184 |         if (roulette[method]) {
 | 
| 185 |           roulette[method](options);
 | 
| 186 |         } else {
 | 
| 187 |           console && console.error('Method ' + method + ' does not exist on jQuery.roulette');
 | 
| 188 |         }
 | 
| 189 |       } else {
 | 
| 190 |         roulette = new Roulette(method);
 | 
| 191 |         roulette.init(self, method);
 | 
| 192 |         $(this).data('plugin_' + pluginName, roulette);
 | 
| 193 |       }
 | 
| 194 |     });
 | 
| 195 |   }
 | 
| 196 | })(jQuery);
 |