1////////////////////////////////////////////////////////////////////////////////// 2// CloudCarousel V1.0.5 3// (c) 2011 by R Cecco. <http://www.professorcloud.com> 4// MIT License 5// 6// Reflection code based on plugin by Christophe Beyls <http://www.digitalia.be> 7// 8// Please retain this copyright header in all versions of the software 9////////////////////////////////////////////////////////////////////////////////// 10 11(function($) { 12 13 // START Reflection object. 14 // Creates a reflection for underneath an image. 15 // IE uses an image with IE specific filter properties, other browsers use the Canvas tag. 16 // The position and size of the reflection gets updated by updateAll() in Controller. 17 function Reflection(img, reflHeight, opacity) { 18 19 var reflection, cntx, imageWidth = img.width, imageHeight = img.width, gradient, parent; 20 21 parent = $(img.parentNode); 22 this.element = reflection = parent.append("<canvas class='reflection' style='position:absolute'/>").find(':last')[0]; 23 if ( !reflection.getContext && $.browser.msie) { 24 this.element = reflection = parent.append("<img class='reflection' style='position:absolute'/>").find(':last')[0]; 25 reflection.src = img.src; 26 reflection.style.filter = "flipv progid:DXImageTransform.Microsoft.Alpha(opacity=" + (opacity * 100) + ", style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=" + (reflHeight / imageHeight * 100) + ")"; 27 28 } else { 29 cntx = reflection.getContext("2d"); 30 try { 31 32 33 $(reflection).attr({width: imageWidth, height: reflHeight}); 34 cntx.save(); 35 cntx.translate(0, imageHeight-1); 36 cntx.scale(1, -1); 37 cntx.drawImage(img, 0, 0, imageWidth, imageHeight); 38 cntx.restore(); 39 cntx.globalCompositeOperation = "destination-out"; 40 gradient = cntx.createLinearGradient(0, 0, 0, reflHeight); 41 gradient.addColorStop(0, "rgba(255, 255, 255, " + (1 - opacity) + ")"); 42 gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)"); 43 cntx.fillStyle = gradient; 44 cntx.fillRect(0, 0, imageWidth, reflHeight); 45 } catch(e) { 46 return; 47 } 48 } 49 // Store a copy of the alt and title attrs into the reflection 50 $(reflection).attr({ 'alt': $(img).attr('alt'), title: $(img).attr('title')} ); 51 52 } //END Reflection object 53 54 // START Item object. 55 // A wrapper object for items within the carousel. 56 var Item = function(imgIn, options) 57 { 58 this.orgWidth = imgIn.width; 59 this.orgHeight = imgIn.height; 60 this.image = imgIn; 61 this.reflection = null; 62 this.alt = imgIn.alt; 63 this.title = imgIn.title; 64 this.imageOK = false; 65 this.options = options; 66 67 this.imageOK = true; 68 69 if (this.options.reflHeight > 0) 70 { 71 this.reflection = new Reflection(this.image, this.options.reflHeight, this.options.reflOpacity); 72 } 73 $(this.image).css('position','absolute'); // Bizarre. This seems to reset image width to 0 on webkit! 74 };// END Item object 75 76 77 // Controller object. 78 // This handles moving all the items, dealing with mouse clicks etc. 79 var Controller = function(container, images, options) 80 { 81 var items = [], funcSin = Math.sin, funcCos = Math.cos, ctx=this; 82 this.controlTimer = 0; 83 this.stopped = false; 84 //this.imagesLoaded = 0; 85 this.container = container; 86 this.xRadius = options.xRadius; 87 this.yRadius = options.yRadius; 88 this.showFrontTextTimer = 0; 89 this.autoRotateTimer = 0; 90 if (options.xRadius === 0) 91 { 92 this.xRadius = ($(container).width()/2.3); 93 } 94 if (options.yRadius === 0) 95 { 96 this.yRadius = ($(container).height()/6); 97 } 98 99 this.xCentre = options.xPos; 100 this.yCentre = options.yPos; 101 this.frontIndex = 0; // Index of the item at the front 102 103 // Start with the first item at the front. 104 this.rotation = this.destRotation = Math.PI/2; 105 this.timeDelay = 1000/options.FPS; 106 107 // Turn on the infoBox 108 if(options.altBox !== null) 109 { 110 $(options.altBox).css('display','block'); 111 $(options.titleBox).css('display','block'); 112 } 113 // Turn on relative position for container to allow absolutely positioned elements 114 // within it to work. 115 $(container).css({ position:'relative', overflow:'hidden'} ); 116 117 $(options.buttonLeft).css('display','inline'); 118 $(options.buttonRight).css('display','inline'); 119 120 // Setup the buttons. 121 $(options.buttonLeft).bind('mouseup',this,function(event){ 122 event.data.rotate(-1); 123 return false;
124 }); 125 $(options.buttonRight).bind('mouseup',this,function(event){ 126 event.data.rotate(1); 127 return false; 128 }); 129 130 // You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel 131 if (options.mouseWheel) 132 { 133 $(container).bind('mousewheel',this,function(event, delta) { 134 event.data.rotate(delta); 135 return false; 136 }); 137 } 138 $(container).bind('mouseover click',this,function(event){ 139 140 clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over. 141 var text = $(event.target).attr('alt'); 142 // If we have moved over a carousel item, then show the alt and title text. 143 144 if ( text !== undefined && text !== null ) 145 { 146 147 clearTimeout(event.data.showFrontTextTimer); 148 $(options.altBox).html( ($(event.target).attr('alt') )); 149 $(options.titleBox).html( ($(event.target).attr('title') )); 150 if ( options.bringToFront && event.type == 'click' ) 151 { 152 153 var idx = $(event.target).data('itemIndex'); 154 var frontIndex = event.data.frontIndex; 155 //var diff = idx - frontIndex; 156 var diff = (idx - frontIndex) % images.length; 157 if (Math.abs(diff) > images.length / 2) { 158 diff += (diff > 0 ? -images.length : images.length); 159 } 160 161 event.data.rotate(-diff); 162 } 163 } 164 }); 165 // If we have moved out of a carousel item (or the container itself), 166 // restore the text of the front item in 1 second. 167 $(container).bind('mouseout',this,function(event){ 168 var context = event.data; 169 clearTimeout(context.showFrontTextTimer); 170 context.showFrontTextTimer = setTimeout( function(){context.showFrontText();},1000); 171 context.autoRotate(); // Start auto rotation. 172 }); 173 174 // Prevent items from being selected as mouse is moved and clicked in the container. 175 $(container).bind('mousedown',this,function(event){ 176 177 event.data.container.focus(); 178 return false; 179 }); 180 container.onselectstart = function () { return false; }; // For IE. 181 182 this.innerWrapper = $(container).wrapInner('<div style="position:absolute;width:100%;height:100%;"/>').children()[0]; 183 184 // Shows the text from the front most item. 185 this.showFrontText = function() 186 { 187 if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet. 188 $(options.titleBox).html( $(items[this.frontIndex].image).attr('title')); 189 $(options.altBox).html( $(items[this.frontIndex].image).attr('alt')); 190 }; 191 192 this.go = function() 193 { 194 if(this.controlTimer !== 0) { return; } 195 var context = this; 196 this.controlTimer = setTimeout( function(){context.updateAll();},this.timeDelay); 197 }; 198 199 this.stop = function() 200 { 201 clearTimeout(this.controlTimer); 202 this.controlTimer = 0; 203 }; 204 205 206 // Starts the rotation of the carousel. Direction is the number (+-) of carousel items to rotate by. 207 this.rotate = function(direction) 208 { 209 this.frontIndex -= direction; 210 this.frontIndex %= items.length; 211 this.destRotation += ( Math.PI / items.length ) * ( 2*direction ); 212 this.showFrontText(); 213 this.go(); 214 }; 215 216 217 this.autoRotate = function() 218 { 219 if ( options.autoRotate !== 'no' ) 220 { 221 var dir = (options.autoRotate === 'right')? 1 : -1; 222 this.autoRotateTimer = setInterval( function(){ctx.rotate(dir); }, options.autoRotateDelay ); 223 } 224 }; 225 226 // This is the main loop function that moves everything. 227 this.updateAll = function() 228 { 229 var minScale = options.minScale; // This is the smallest scale applied to the furthest item. 230 var smallRange = (1-minScale) * 0.5; 231 var w,h,x,y,scale,item,sinVal; 232 233 var change = (this.destRotation - this.rotation); 234 var absChange = Math.abs(change); 235 236 this.rotation += change * options.speed; 237 if ( absChange < 0.001 ) { this.rotation = this.destRotation; } 238 var itemsLen = items.length; 239 var spacing = (Math.PI / itemsLen) * 2; 240 //var wrapStyle = null; 241 var radians = this.rotation; 242 var isMSIE = $.browser.msie; 243 244 // Turn off display. This can reduce repaints/reflows when making style and position changes in the loop. 245 // See http://dev.opera.com/articles/view/efficient-javascript/?page=3 246 this.innerWrapper.style.display = 'none'; 247 248 var style; 249 var px = 'px', reflHeight; 250 var context = this; 251 for (var i = 0; i<itemsLen ;i++) 252 { 253 item = items[i]; 254 255 sinVal = funcSin(radians); 256 257 scale = ((sinVal+1) * smallRange) + minScale; 258 259 x = this.xCentre + (( (funcCos(radians) * this.xRadius) - (item.orgWidth*0.5)) * scale); 260 y = this.yCentre + (( (sinVal * this.yRadius) ) * scale); 261 262 if (item.imageOK) 263 { 264 var img = item.image; 265 w = img.width = item.orgWidth * scale;
266 h = img.height = item.orgHeight * scale; 267 img.style.left = x + px ; 268 img.style.top = y + px; 269 img.style.zIndex = "" + (scale * 100)>>0; // >>0 = Math.foor(). Firefox doesn't like fractional decimals in z-index. 270 if (item.reflection !== null) 271 { 272 reflHeight = options.reflHeight * scale; 273 style = item.reflection.element.style; 274 style.left = x + px; 275 style.top = y + h + options.reflGap * scale + px; 276 style.width = w + px; 277 if (isMSIE) 278 { 279 style.filter.finishy = (reflHeight / h * 100); 280 }else 281 { 282 style.height = reflHeight + px; 283 } 284 } 285 } 286 radians += spacing; 287 } 288 // Turn display back on. 289 this.innerWrapper.style.display = 'block'; 290 291 // If we have a preceptable change in rotation then loop again next frame. 292 if ( absChange >= 0.001 ) 293 { 294 this.controlTimer = setTimeout( function(){context.updateAll();},this.timeDelay); 295 }else 296 { 297 // Otherwise just stop completely. 298 this.stop(); 299 } 300 }; // END updateAll 301 302 // Create an Item object for each image 303// func = function(){return;ctx.updateAll();} ; 304 305 // Check if images have loaded. We need valid widths and heights for the reflections. 306 this.checkImagesLoaded = function() 307 { 308 var i; 309 for(i=0;i<images.length;i++) { 310 if ( (images[i].width === undefined) || ( (images[i].complete !== undefined) && (!images[i].complete) )) 311 { 312 return; 313 } 314 } 315 for(i=0;i<images.length;i++) { 316 items.push( new Item( images[i], options ) ); 317 $(images[i]).data('itemIndex',i); 318 } 319 // If all images have valid widths and heights, we can stop checking. 320 clearInterval(this.tt); 321 this.showFrontText(); 322 this.autoRotate(); 323 this.updateAll(); 324 325 }; 326 327 this.tt = setInterval( function(){ctx.checkImagesLoaded();},50); 328 }; // END Controller object 329 330 // The jQuery plugin part. Iterates through items specified in selector and inits a Controller class for each one. 331 $.fn.CloudCarousel = function(options) { 332 333 this.each( function() { 334 335 options = $.extend({}, { 336 reflHeight:0, 337 reflOpacity:0.5, 338 reflGap:0, 339 minScale:0.5, 340 xPos:0, 341 yPos:0, 342 xRadius:0, 343 yRadius:0, 344 altBox:null, 345 titleBox:null, 346 FPS: 30, 347 autoRotate: 'no', 348 autoRotateDelay: 1500, 349 speed:0.2, 350 mouseWheel: false, 351 bringToFront: false 352 },options ); 353 // Create a Controller for each carousel. 354 $(this).data('cloudcarousel', new Controller( this, $('.cloudcarousel',$(this)), options) ); 355 }); 356 return this; 357 }; 358 359})(jQuery); 360 361
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.