PageSourceSearch

https://zagoraem.ru/js/cloud-carousel.1.0.5.js

js zagoraem.ru collected 2026-10-07 00:42:06 UTC 12,129 bytes, 361 lines download raw bytes

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.