PageSourceSearch

https://sah.rs/js/em/cloud-zoom.1.0.2.js

js sah.rs collected 2026-10-06 04:32:15 UTC 17,547 bytes, 442 lines download raw bytes

1//////////////////////////////////////////////////////////////////////////////////
2// Cloud Zoom V1.0.2
3// (c) 2010 by R Cecco. <http://www.professorcloud.com>
4// MIT License
5//
6// Please retain this copyright header in all versions of the software
7//////////////////////////////////////////////////////////////////////////////////
8(function ($) {
9
10    $(window).load(function () {
11        $('.cloud-zoom, .cloud-zoom-gallery').CloudZoom();
12    });
13    $(window).resize(function () {
14    	if ($('.cloud-zoom, .cloud-zoom-gallery').data('zoom') != null){
15	    	$('.cloud-zoom, .cloud-zoom-gallery').data('zoom').destroy();
16	    	$('.cloud-zoom, .cloud-zoom-gallery').CloudZoom();
17    	}
18    });
19    function format(str) {
20        for (var i = 1; i < arguments.length; i++) {
21            str = str.replace('%' + (i - 1), arguments[i]);
22        }
23        return str;
24    }
25
26    function CloudZoom(jWin, opts) {
27        var sImg = $('img', jWin);
28		var	img1;
29		var	img2;
30        var zoomDiv = null;
31		var	$mouseTrap = null;
32		var	lens = null;
33		var	$tint = null;
34		var	softFocus = null;
35		var	$ie6Fix = null;
36		var	zoomImage;
37        var controlTimer = 0;      
38        var cw, ch;
39        var destU = 0;
40		var	destV = 0;
41        var currV = 0;
42        var currU = 0;      
43        var filesLoaded = 0;
44        var mx,
45            my; 
46        var ctx = this, zw;
47        // Display an image loading message. This message gets deleted when the images have loaded and the zoom init function is called.
48        // We add a small delay before the message is displayed to avoid the message flicking on then off again virtually immediately if the
49        // images load really fast, e.g. from the cache. 
50        //var	ctx = this;
51        var  timeout = setTimeout(function () {
52            //						 <img src="/images/loading.gif"/>
53            if ($mouseTrap === null) {
54                var w = jWin.width();
55                jWin.parent().append(format('<div style="width:%0px;position:absolute;top:75%;left:%1px;text-align:center" class="cloud-zoom-loading" >Loading...</div>', w / 3, (w / 2) - (w / 6))).find(':last').css('opacity', 0.5);
56            }
57        }, 200);
58
59
60        var ie6FixRemove = function () {
61
62            if ($ie6Fix !== null) {
63                $ie6Fix.remove();
64                $ie6Fix = null;
65            }
66        };
67
68        // Removes cursor, tint layer, blur layer etc.
69        this.removeBits = function () {
70            //$mouseTrap.unbind();
71            if (lens) {
72                lens.remove();
73                lens = null;             
74            }
75            if ($tint) {
76                $tint.remove();
77                $tint = null;
78            }
79            if (softFocus) {
80                softFocus.remove();
81                softFocus = null;
82            }
83            ie6FixRemove();
84
85            $('.cloud-zoom-loading', jWin.parent()).remove();
86        };
87
88
89        this.destroy = function () {
90            jWin.data('zoom', null);
91            if (sImg) sImg = null;
92            if (timeout) clearTimeout(timeout);
93            if ($mouseTrap) {
94                $mouseTrap.unbind();
95                $mouseTrap.remove();
96                $mouseTrap = null;
97            }
98            if (zoomDiv) {
99                zoomDiv.remove();
100                zoomDiv = null;
101            }
102            //ie6FixRemove();
103            this.removeBits();
104            // DON'T FORGET TO REMOVE JQUERY 'DATA' VALUES
105        };
106
107
108        // This is called when the zoom window has faded out so it can be removed.
109        this.fadedOut = function () {
110            
111			if (zoomDiv) {
112                zoomDiv.remove();
113                zoomDiv = null;
114            }
115			 this.removeBits();
116            //ie6FixRemove();
117        };
118
119        this.controlLoop = function () {
120        	
121            if (lens) {
122                var x = (mx - sImg.offset().left - (cw * 0.5)) >> 0;
123                var y = (my - sImg.offset().top - (ch * 0.5)) >> 0;
124                
125               
126                if (x < 0) {
127                    x = 0;
128                }
129                else if (x > (sImg.outerWidth() - cw)) {
130                    x = (sImg.outerWidth() - cw);
131                }
132                if (y < 0) {
133                    y = 0;
134                }
135                else if (y > (sImg.outerHeight() - ch)) {
136                    y = (sImg.outerHeight() - ch);
137                }
138
139                lens.css({
140                    left: x,
141                    top: y
142                });
143
144                lens.css('background-position', (-x) + 'px ' + (-y) + 'px');
145
146                destU = (((x) / sImg.outerWidth()) * zoomImage.width) >> 0;
147                destV = (((y) / sImg.outerHeight()) * zoomImage.height) >> 0;
148                currU += (destU - currU) / opts.smoothMove;
149                currV += (destV - currV) / opts.smoothMove;
150
151                zoomDiv.css('background-position', (-(currU >> 0) + 'px ') + (-(currV >> 0) + 'px'));              
152            }
153            controlTimer = setTimeout(function () {
154                ctx.controlLoop();
155            }, 30);
156        };
157
158        this.init2 = function (img, id) {
159
160            filesLoaded++;
161            //console.log(img.src + ' ' + id + ' ' + img.width);	
162            if (id === 1) {
163                zoomImage = img;
164            }
165            //this.images[id] = img;
166            if (filesLoaded === 2) {
167                this.init();
168            }
169        };
170
171        /* Init function start.  */
172        this.init = function () {
173            // Remove loading message (if present);
174            $('.cloud-zoom-loading', jWin.parent()).remove();
175
176
177/* Add a box (mouseTrap) over the small image to trap mouse events.
178		It has priority over zoom window to avoid issues with inner zoom.
179		We need the dummy background image as IE does not trap mouse events on
180		transparent parts of a div.
181		*/
182            var widthImg = 0;
183            var heightImg = 0;
184            if(sImg!= null){
185            	widthImg = sImg.outerWidth();
186                heightImg = sImg.outerHeight();
187            }
188	           $mouseTrap = jWin.parent().append(format("<div class='mousetrap' style='background:#fff;opacity:0;filter:alpha(opacity=0);z-index:999;position:absolute;width:%0px;height:%1px;left:%2px;top:%3px;\'></div>", widthImg, heightImg, 0, 0)).find(':last');
189
190			// Detect device type, normal mouse or touchy(ipad android) by albanx
191            var touchy=("ontouchstart" in document.documentElement)?true:false;
192			var m_move='touchmove mousemove';
193			var m_end='touchend mouseleave';
194			var m_ent='touchstart mouseenter';
195			var m_click='touchstart click';
196            //////////////////////////////////////////////////////////////////////			
197            /* Do as little as possible in mousemove event to prevent slowdown. */
198            
199            $mouseTrap.bind(m_move, this, function (e) {
200                // Just update the mouse position         
201            	mx=( typeof(e.originalEvent.touches) !='undefined')?
202            			e.originalEvent.touches[0].pageX:e.pageX;
203            	my=( typeof(e.originalEvent.touches) !='undefined')?
204            			e.originalEvent.touches[0].pageY:e.pageY;
205            });
206            //////////////////////////////////////////////////////////////////////					
207            $mouseTrap.bind(m_end, this, function (event) {
208                clearTimeout(controlTimer);
209                //event.data.removeBits();                
210				if(lens) { lens.fadeOut(299); }
211				if($tint) { $tint.fadeOut(299); }
212				if(softFocus) { softFocus.fadeOut(299); }
213				zoomDiv.fadeOut(300, function () {
214                    ctx.fadedOut();
215                });																
216                return false;
217            });
218            //////////////////////////////////////////////////////////////////////			
219            $mouseTrap.bind(m_ent, this, function (event) {
220            	if(touchy)//i consider only one touches for zooming
221				{
222            		event.preventDefault();
223				}
224            	mx=( typeof(event.originalEvent.touches) !='undefined')?
225            			event.originalEvent.touches[0].pageX:event.pageX;
226            	my=( typeof(event.originalEvent.touches) !='undefined')?
227            			event.originalEvent.touches[0].pageY:event.pageY;
228            			
229                zw = event.data;
230                if (zoomDiv) {
231                    zoomDiv.stop(true, false);
232                    zoomDiv.remove();
233                }
234
235                var xPos = opts.adjustX,
236                    yPos = opts.adjustY;
237                             
238                var siw = sImg.outerWidth();
239                var sih = sImg.outerHeight();
240
241                var w = opts.zoomWidth;
242                var h = opts.zoomHeight;
243                if (opts.zoomWidth == 'auto') {
244                    w = siw;
245                }
246                if (opts.zoomHeight == 'auto') {
247                    h = sih;
248                }
249                //$('#info').text( xPos + ' ' + yPos + ' ' + siw + ' ' + sih );
250                var appendTo = jWin.parent(); // attach to the wrapper			
251                switch (opts.position) {
252                case 'top':
253                    yPos -= h; // + opts.adjustY;
254                    break;
255                case 'right':
256                    xPos += siw; // + opts.adjustX;					
257                    break;
258                case 'bottom':
259                    yPos += sih; // + opts.adjustY;
260                    break;
261                case 'left':
262                    xPos -= w; // + opts.adjustX;					
263                    break;
264                case 'inside':
265                    w = siw;
266                    h = sih;
267                    break;
268                    // All other values, try and find an id in the dom to attach to.
269                default:
270                    appendTo = $('#' + opts.position);
271                    // If dom element doesn't exit, just use 'right' position as default.
272                    if (!appendTo.length) {
273                        appendTo = jWin;
274                        xPos += siw; //+ opts.adjustX;
275                        yPos += sih; // + opts.adjustY;	
276                    } else {
277                        w = appendTo.innerWidth();
278                        h = appendTo.innerHeight();
279                    }
280                }
281
282                zoomDiv = appendTo.append(format('<div id="cloud-zoom-big" class="cloud-zoom-big" style="display:none;position:absolute;left:%0px;top:%1px;width:%2px;height:%3px;background-image:url(\'%4\');z-index:99;"></div>', xPos, yPos, w, h, zoomImage.src)).find(':last');
283
284                // Add the title from title tag.
285                if (sImg.attr('title') && opts.showTitle) {
286                    zoomDiv.append(format('<div class="cloud-zoom-title">%0</div>', sImg.attr('title'))).find(':last').css('opacity', opts.titleOpacity);
287                }
288
289                // Fix ie6 select elements wrong z-index bug. Placing an iFrame over the select element solves the issue...		
290                if ($.browser.msie && $.browser.version < 7) {
291                    $ie6Fix = $('<iframe frameborder="0" src="#"></iframe>').css({
292                        position: "absolute",
293                        left: xPos,
294                        top: yPos,
295                        zIndex: 99,
296                        width: w,
297                        height: h
298                    }).insertBefore(zoomDiv);
299                }
300
301                zoomDiv.fadeIn(500);
302
303                if (lens) {
304                    lens.remove();
305                    lens = null;
306                } /* Work out size of cursor */
307                if(typeof event.data.zoomDivWidth == 'undefined'){
308                	event.data.zoomDivWidth = zoomDiv.get(0).offsetWidth - (zoomDiv.css('border-left-width').replace(/\D/g, '')*1) - (zoomDiv.css('border-right-width').replace(/\D/g, '')*1);
309                }
310                if(typeof event.data.zoomDivHeight == 'undefined'){
311                	event.data.zoomDivHeight = zoomDiv.get(0).offsetHeight - (zoomDiv.css('border-top-width').replace(/\D/g, '')*1) - (zoomDiv.css('border-bottom-width').replace(/\D/g, '')*1);
312                }
313                
314                cw = (sImg.outerWidth() / zoomImage.width) * event.data.zoomDivWi
314dth;
315                if(cw > event.data.zoomDivWidth)
316					cw = Math.min(sImg.outerWidth(),event.data.zoomDivWidth);
317				
318                ch = (sImg.outerHeight() / zoomImage.height) * event.data.zoomDivHeight;
319				
320				if(ch > event.data.zoomDivHeight)
321					ch = Math.min(sImg.outerHeight(),event.data.zoomDivHeight);
322					
323                // Attach mouse, initially invisible to prevent first frame glitch
324                lens = jWin.append(format("<div class = 'cloud-zoom-lens' style='display:none;z-index:98;position:absolute;width:%0px;height:%1px;'></div>", cw, ch)).find(':last');
325
326                $mouseTrap.css('cursor', lens.css('cursor'));
327
328                var noTrans = false;
329
330                // Init tint layer if needed. (Not relevant if using inside mode)			
331                if (opts.tint) {
332                    lens.css('background', 'url("' + sImg.attr('src') + '")');
333                    $tint = jWin.append(format('<div style="display:none;position:absolute; left:0px; top:0px; width:%0px; height:%1px; background-color:%2;" />', sImg.outerWidth(), sImg.outerHeight(), opts.tint)).find(':last');
334                    $tint.css('opacity', opts.tintOpacity);                    
335					noTrans = true;
336					$tint.fadeIn(500);
337
338                }
339                if (opts.softFocus) {
340                    lens.css('background', 'url("' + sImg.attr('src') + '")');
341                    softFocus = jWin.append(format('<div style="position:absolute;display:none;top:2px; left:2px; width:%0px; height:%1px;" />', sImg.outerWidth() - 2, sImg.outerHeight() - 2, opts.tint)).find(':last');
342                    softFocus.css('background', 'url("' + sImg.attr('src') + '")');
343                    softFocus.css('opacity', 0.5);
344                    noTrans = true;
345                    softFocus.fadeIn(500);
346                }
347
348                if (!noTrans) {
349                    lens.css('opacity', opts.lensOpacity);										
350                }
351				if ( opts.position !== 'inside' ) { lens.fadeIn(500); }
352
353                // Start processing. 
354                zw.controlLoop();
355
356                return; // Don't return false here otherwise opera will not detect change of the mouse pointer type.
357            });
358        };
359
360        img1 = new Image();
361        $(img1).load(function () {
362            ctx.init2(this, 0);
363        });
364        img1.src = sImg.attr('src');
365
366        img2 = new Image();
367        $(img2).load(function () {
368            ctx.init2(this, 1);
369        });
370        img2.src = jWin.attr('href');
371    }
372
373    $.fn.CloudZoom = function (options) {
374        // IE6 background image flicker fix
375        try {
376            document.execCommand("BackgroundImageCache", false, true);
377        } catch (e) {}
378        this.each(function () {
379		var touchy=("ontouchstart" in document.documentElement)?true:false;
380			var m_move='touchmove mousemove';
381			var m_end='touchend mouseleave';
382			var m_ent='touchstart mouseenter';
383			var m_click='touchstart click';
384		
385			var	relOpts, opts;
386			// Hmm...eval...slap on wrist.
387			eval('var	a = {' + $(this).attr('rel') + '}');
388			relOpts = a;
389            if ($(this).is('.cloud-zoom')) {
390                $(this).css({
391                    'position': 'relative',
392                    'display': 'block'
393                });
394                $('img', $(this)).css({
395                    'display': 'block'
396                });
397                // Wrap an outer div around the link so we can attach things without them becoming part of the link.
398                // But not if wrap already exists.
399                if ($(this).parent().attr('id') != 'wrap') {
400                    $(this).wrap('<div id="wrap" style="top:0px;z-index:9999;position:relative;"></div>');
401                }
402                opts = $.extend({}, $.fn.CloudZoom.defaults, options);
403                opts = $.extend({}, opts, relOpts);
404                $(this).data('zoom', new CloudZoom($(this), opts));
405
406            } else if ($(this).is('.cloud-zoom-gallery')) {
407                opts = $.extend({}, relOpts, options);
408                $(this).data('relOpts', opts);
409                $(this).bind(m_click, $(this), function (event) {
410                    var data = event.data.data('relOpts');
411                    // Destroy the previous zoom
412                    $('#' + data.useZoom).data('zoom').destroy();
413                    // Change the biglink to point to the new big image.
414                    $('#' + data.useZoom).attr('href', event.data.attr('href'));
415                    // Change the small image to point to the new small image.
416                    $('#' + data.useZoom + ' img').attr('src', event.data.data('relOpts').smallImage);
417					$('#' + data.useZoom + ' img').attr('title', $(this).attr('title'));
418                    // Init a new zoom with the new images.				
419                    $('#' + event.data.data('relOpts').useZoom).CloudZoom();
420                    return false;
421                });
422            }
423        });
424        return this;
425    };
426
427    $.fn.CloudZoom.defaults = {
428        zoomWidth: 'auto',
429        zoomHeight: 'auto',
430        position: 'right',
431        tint: false,
432        tintOpacity: 0.5,
433        lensOpacity: 0.5,
434        softFocus: false,
435        smoothMove: 3,
436        showTitle: true,
437        titleOpacity: 0.5,
438        adjustX: 0,
439        adjustY: 0
440    };
441
442})(jQuery);

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.