1 2// Multi-Zoom Script (c)2012 John Davenport Scheuer 3// as first seen in http://www.dynamicdrive.com/forums/ 4// username: jscheuer1 - This Notice Must Remain for Legal Use 5// requires: a modified version of Dynamic Drive's Featured Image Zoomer (w/ adjustable power) (included) 6 7/*Featured Image Zoomer (May 8th, 2010) 8* This notice must stay intact for usage 9* Author: Dynamic Drive at http://www.dynamicdrive.com/ 10* Visit http://www.dynamicdrive.com/ for full source code 11*/ 12 13// Feb 21st, 2011: Script updated to v1.5, which now includes new feature by jscheuer1 (http://www.dynamicdrive.com/forums/member.php?u=2033) to show optional "magnifying lens" while over thumbnail image. 14// March 1st, 2011: Script updated to v1.51. Minor improvements to inner workings of script. 15// July 9th, 12': Script updated to v1.5.1, which fixes mouse wheel issue with script when used with a more recent version of jQuery. 16// Nov 5th, 2012: Unofficial update to v1.5.1m for integration with multi-zoom (adds multiple images to be zoomed via thumbnail activated image swapping) 17// Nov 28th, 2012: Version 2.1 w/Multi Zoom, updates - new features and bug fixes 18 19var featuredimagezoomer = { // the two options for Featured Image Zoomer: 20 loadinggif: 'spinningred.gif', // full path or URL to "loading" gif 21 magnifycursor: 'crosshair' // value for CSS's 'cursor' property when over the zoomable image 22}; 23 24 //////////////// No Need To Edit Beyond Here //////////////// 25 26jQuery.noConflict(); 27 28(function($){ 29 30 $('head').append('<style type="text/css">.featuredimagezoomerhidden {visibility: hidden!important;}</style>'); 31 32 $.fn.multizoomhide = function(){ 33 return $('<style type="text/css">' + this.selector + ' {visibility: hidden;}<\/style>').appendTo('head'); 34 }; 35 36 $.fn.addmultizoom = function(options){ 37 38 var indoptions = {largeimage: options.largeimage}, $imgObj = $(options.imgObj + ':not(".thumbs")'), 39 $descArea = $(options.descArea), first = true, splitre = /, ?/; 40 41 options = $.extend({ 42 speed: 'slow', 43 initzoomablefade: true, 44 zoomablefade: true 45 }, options); 46 47 function loadfunction(){ 48 var lnk = this, styleobj1 = {}, styleobj2 = {}, $nim, lnkd, lnkt, lnko, w, h; 49 if((lnkd = lnk.getAttribute('data-dims'))){ 50 lnkd = lnkd.split(splitre); 51 w = lnkd[0]; h = lnkd[1]; 52 } 53 $(new Image()).error(function(){ 54 if(lnk.tagName && !options.notmulti){ 55 alert("Error: I couldn't find the image:\n\n" + lnk.href + ((lnkt = lnk.getAttribute('data-title'))? '\n\n"' + lnkt + '"' : '')); 56 if((lnko = $imgObj.data('last-trigger'))){ 57 first = true; 58 $(lnko).trigger('click'); 59 } 60 } 61 }).load(function(){ 62 var opacity = $imgObj.css('opacity'), combinedoptions = {}, $parent; 63 if(isNaN(opacity)){opacity = 1;} 64 if(options.notmulti || !indoptions.largeimage){ 65 w = options.width || $imgObj.width(); h = options.height || $imgObj.height(); 66 } 67 $imgObj.attr('src', this.src).css({width: w || options.width || this.width, height: (h = +(h || options.height || this.height))}); 68 if($imgObj.data('added')) {$imgObj.data('added').remove()}; 69 $imgObj.data('last-trigger', lnk); 70 if(options.imagevertcenter){styleobj1 = {top: ($imgObj.parent().innerHeight() - h) / 2};} 71 $imgObj.css(styleobj1).addimagezoom($.extend(combinedoptions, options, indoptions)) 72 .data('added', $('.magnifyarea:last' + (combinedoptions.cursorshade? ', .cursorshade:last' : '') + ', .zoomstatus:last, .zoomtracker:last')); 73 if(options.magvertcenter){ 74 $('.magnifyarea:last').css({marginTop: (h - $('.magnifyarea:last').height()) / 2}); 75 } 76 if(options.descpos){ 77 $parent = $imgObj.parent(); 78 styleobj2 = {left: $parent.offset().left + ($parent.outerWidth() - $parent.width()) / 2, top: h + $imgObj.offset().top}; 79 } 80 if(options.notmulti){ 81 $descArea.css(styleobj2); 82 } else { 83 $descArea.css(styleobj2).empty().append(lnk.getAttribute('data-title') || ''); 84 } 85 if(+opacity < 1){$imgObj.add($descArea).animate({opacity: 1}, options.speed);} 86 }).attr('src', $imgObj.data('src')); 87 } 88 89 this.click(function(e){ 90 e.preventDefault(); 91 var src = $imgObj.attr('src'), ms, zr, cs, opacityObj = {opacity: 0}; 92 if(!first && (src === this.href || src === this.getAttribute('href'))){return;} 93 if(first && !options.initzoomablefade || !options.zoomablefade){opacityObj = {};} 94 first = false;
95 indoptions.largeimage = this.getAttribute('data-large') || options.largeimage || ''; 96 if(indoptions.largeimage === 'none'){indoptions.largeimage = '';} 97 if((ms = this.getAttribute('data-magsize')) || options.magnifiersize){ 98 indoptions.magnifiersize = (ms? ms.split(splitre) : '') || options.magnifiersize; 99 } else {delete indoptions.magnifiersize;} 100 indoptions.zoomrange = ((zr = this.getAttribute('data-zoomrange'))? (zr = zr.split(splitre)) : '') || options.zoomrange || ''; 101 if(zr){zr[0] = +zr[0]; zr[1] = +zr[1];} 102 indoptions.cursorshade = ((cs = this.getAttribute('data-lens'))? cs : '') || options.cursorshade || ''; 103 if(cs){indoptions.cursorshade = eval(cs);} 104 $imgObj.data('added') && 105 $imgObj.stop(true, true).data('added').not('.zoomtracker').remove().end() 106 .css({background: 'url(' + featuredimagezoomer.loadinggif + ') center no-repeat'}); 107 $imgObj.css($.extend({visibility: 'visible'}, ($imgObj.data('added')? options.zoomablefade? {opacity: 0.25} : opacityObj : opacityObj))).data('src', this.href); 108 if ($descArea.css('position') == 'absolute') 109 $(document.body).append($descArea); 110 $descArea.css($.extend({visibility: 'visible'}, opacityObj)); 111 loadfunction.call(this); 112 }).eq(0).trigger('click'); 113 114 return this; 115 }; 116 117 // Featured Image Zoomer main code: 118 119 $.extend(featuredimagezoomer, { 120 121 dsetting: { //default settings 122 magnifierpos: 'right', 123 magnifiersize:[200, 200], 124 cursorshadecolor: '#fff', 125 cursorshadeopacity: 0.3, 126 cursorshadeborder: '1px solid black', 127 cursorshade: false, 128 leftoffset: 15, //offsets here are used (added to) the width of the magnifyarea when 129 rightoffset: 10 //calculating space requirements and to position it visa vis any drop shadow 130 }, 131 132 isie: (function(){/*@cc_on @*//*@if(@_jscript_version >= 5)return true;@end @*/return false;})(), //is this IE? 133 134 showimage: function($tracker, $mag, showstatus){ 135 var specs=$tracker.data('specs'), d=specs.magpos, fiz=this; 136 var coords=$tracker.data('specs').coords //get coords of tracker (from upper corner of document) 137 specs.windimensions={w:$(window).width(), h:$(window).height()}; //remember window dimensions 138 var magcoords={} //object to store coords magnifier DIV should move to 139 magcoords.left = coords.left + (d === 'left'? -specs.magsize.w - specs.lo : $tracker.width() + specs.ro); 140 //switch sides for magnifiers that don't have enough room to display on the right if there's room on the left: 141 if(d!=='left' && magcoords.left + specs.magsize.w + specs.lo >= specs.windimensions.w && coords.left - specs.magsize.w >= specs.lo){ 142 magcoords.left = coords.left - specs.magsize.w - specs.lo; 143 } else if(d==='left' && magcoords.left < specs.ro) { //if there's no room on the left, move to the right 144 magcoords.left = coords.left + $tracker.width() + specs.ro; 145 } 146 $mag.css({left: magcoords.left, top:coords.top}).show(); //position magnifier DIV on page 147 specs.$statusdiv.html('Current Zoom: '+specs.curpower+'<div style="font-size:80%">Use Mouse Wheel to Zoom In/Out</div>'); 148 if (showstatus) //show status DIV? (only when a range of zoom is defined) 149 fiz.showstatusdiv(specs, 400, 2000); 150 }, 151 152 hideimage: function($tracker, $mag, showstatus){ 153 var specs=$tracker.data('specs'); 154 $mag.hide(); 155 if (showstatus) 156 this.hidestatusdiv(specs); 157 }, 158 159 showstatusdiv: function(specs, fadedur, showdur){ 160 clearTimeout(specs.statustimer) 161 specs.$statusdiv.css({visibility: 'visible'}).fadeIn(fadedur) //show status div 162 specs.statustimer=setTimeout(function(){featuredimagezoomer.hidestatusdiv(specs)}, showdur) //hide status div after delay 163 }, 164 165 hidestatusdiv: function(specs){ 166 specs.$statusdiv.stop(true, true).hide() 167 }, 168 169 getboundary: function(b, val, specs){ //function to set x and y boundaries magnified image can move to (moved outside moveimage for efficiency) 170 if (b=="left"){ 171 var rb=-specs.imagesize.w*specs.curpower+specs.magsize.w 172 return (val>0)? 0 : (val<rb)? rb : val 173 } 174 else{ 175 var tb=-specs.imagesize.h*specs.curpower+specs.magsize.h 176 return (val>0)? 0 : (val<tb)? tb : val 177 } 178 }, 179
180 moveimage: function($tracker, $maginner, $cursorshade, e){ 181 var specs=$tracker.data('specs'), csw = Math.round(specs.magsize.w/specs.curpower), csh = Math.round(specs.magsize.h/specs.curpower), 182 csb = specs.csborder, fiz = this, imgcoords=specs.coords, pagex=(e.pageX || specs.lastpagex), pagey=(e.pageY || specs.lastpagey), 183 x=pagex-imgcoords.left, y=pagey-imgcoords.top; 184 $cursorshade.css({ // keep shaded area sized and positioned proportionately to area being magnified 185 visibility: '', 186 width: csw, 187 height: csh, 188 top: Math.min(specs.imagesize.h-csh-csb, Math.max(0, y-(csb+csh)/2)) + imgcoords.top, 189 left: Math.min(specs.imagesize.w-csw-csb, Math.max(0, x-(csb+csw)/2)) + imgcoords.left 190 }); 191 var newx=-x*specs.curpower+specs.magsize.w/2 //calculate x coord to move enlarged image 192 var newy=-y*specs.curpower+specs.magsize.h/2 193 $maginner.css({left:fiz.getboundary('left', newx, specs), top:fiz.getboundary('top', newy, specs)}) 194 specs.$statusdiv.css({left:pagex-10, top:pagey+20}) 195 specs.lastpagex=pagex //cache last pagex value (either e.pageX or lastpagex), as FF1.5 returns undefined for e.pageX for "DOMMouseScroll" event 196 specs.lastpagey=pagey 197 }, 198 199 magnifyimage: function($tracker, e, zoomrange){ 200 if (!e.detail && !e.wheelDelta){e = e.originalEvent;} 201 var delta=e.detail? e.detail*(-120) : e.wheelDelta //delta returns +120 when wheel is scrolled up, -120 when scrolled down 202 var zoomdir=(delta<=-120)? "out" : "in" 203 var specs=$tracker.data('specs') 204 var magnifier=specs.magnifier, od=specs.imagesize, power=specs.curpower 205 var newpower=(zoomdir=="in")? Math.min(power+1, zoomrange[1]) : Math.max(power-1, zoomrange[0]) //get new power 206 var nd=[od.w*newpower, od.h*newpower] //calculate dimensions of new enlarged image within magnifier 207 magnifier.$image.css({width:nd[0], height:nd[1]}) 208 specs.curpower=newpower //set current power to new power after magnification 209 specs.$statusdiv.html('Current Zoom: '+specs.curpower) 210 this.showstatusdiv(specs, 0, 500) 211 $tracker.trigger('mousemove') 212 }, 213 214 highestzindex: function($img){ 215 var z = 0, $els = $img.parents().add($img), elz; 216 $els.each(function(){ 217 elz = $(this).css('zIndex'); 218 elz = isNaN(elz)? 0 : +elz; 219 z = Math.max(z, elz); 220 }); 221 return z; 222 }, 223 224 init: function($img, options){ 225 var setting=$.extend({}, this.dsetting, options), w = $img.width(), h = $img.height(), o = $img.offset(), 226 fiz = this, $tracker, $cursorshade, $statusdiv, $magnifier, lastpage = {pageX: 0, pageY: 0}, 227 basezindex = setting.zIndex || this.highestzindex($img); 228 if(h === 0 || w === 0){ 229 $(new Image()).load(function(){ 230 featuredimagezoomer.init($img, options); 231 }).attr('src', $img.attr('src')); 232 return; 233 } 234 $img.css({visibility: 'visible'}); 235 setting.largeimage = setting.largeimage || $img.get(0).src; 236 $magnifier=$('<div class="magnifyarea" style="position:absolute;z-index:'+basezindex+';width:'+setting.magnifiersize[0]+'px;height:'+setting.magnifiersize[1]+'px;left:-10000px;top:-10000px;visibility:hidden;overflow:hidden;border:1px solid black;" />') 237 .append('<div style="position:relative;left:0;top:0;z-index:'+basezindex+';" />') 238 .appendTo(document.body) //create magnifier container 239 //following lines - create featured image zoomer divs, and absolutely positioned them for placement over the thumbnail and each other: 240 if(setting.cursorshade){ 241 $cursorshade = $('<div class="cursorshade" style="visibility:hidden;position:absolute;left:0;top:0;z-index:'+basezindex+';" />') 242 .css({border: setting.cursorshadeborder, opacity: setting.cursorshadeopacity, backgroundColor: setting.cursorshadecolor}) 243 .appendTo(document.body); 244 } else { 245 $cursorshade = $('<div />'); //dummy shade div to satisfy $tracker.data('specs') 246 } 247 $statusdiv = $('<div class="zoomstatus preloadevt" style="position:absolute;visibility:hidden;left:0;top:0;z-index:'+basezindex+';" />') 248 .html('<img src="'+this.loadinggif+'" />') 249 .appendTo(document.body); //create DIV to show "loading" gif/ "Current Zoom" info
250 $tracker = $('<div class="zoomtracker" style="cursor:progress;position:absolute;z-index:'+basezindex+';left:'+o.left+'px;top:'+o.top+'px;height:'+h+'px;width:'+w+'px;" />') 251 .css({backgroundImage: (this.isie? 'url(cannotbe)' : 'none')}) 252 .appendTo(document.body); 253 $(window).bind('load resize', function(){ //in case resizing the window repostions the image or description 254 var o = $img.offset(), $parent; 255 $tracker.css({left: o.left, top: o.top}); 256 if(options.descpos && options.descArea){ 257 $parent = $img.parent(); 258 $(options.descArea).css({left: $parent.offset().left + ($parent.outerWidth() - $parent.width()) / 2, top: $img.height() + o.top}); 259 } 260 }); 261 262 function getspecs($maginner, $bigimage){ //get specs function 263 var magsize={w:$magnifier.width(), h:$magnifier.height()} 264 var imagesize={w:w, h:h} 265 var power=(setting.zoomrange)? setting.zoomrange[0] : ($bigimage.width()/w).toFixed(5) 266 $tracker.data('specs', { 267 $statusdiv: $statusdiv, 268 statustimer: null, 269 magnifier: {$outer:$magnifier, $inner:$maginner, $image:$bigimage}, 270 magsize: magsize, 271 magpos: setting.magnifierpos, 272 imagesize: imagesize, 273 curpower: power, 274 coords: getcoords(), 275 csborder: $cursorshade.outerWidth(), 276 lo: setting.leftoffset, 277 ro: setting.rightoffset 278 }) 279 } 280 281 function getcoords(){ //get coords of thumb image function 282 var offset=$tracker.offset() //get image's tracker div's offset from document 283 return {left:offset.left, top:offset.top} 284 } 285 286 $tracker.mouseover(function(e){ 287 $cursorshade.add($magnifier).add($statusdiv).removeClass('featuredimagezoomerhidden'); 288 $tracker.data('premouseout', false); 289 }).mouseout(function(e){ 290 $cursorshade.add($magnifier).add($statusdiv.not('.preloadevt')).addClass('featuredimagezoomerhidden'); 291 $tracker.data('premouseout', true); 292 }).mousemove(function(e){ //save tracker mouse position for initial magnifier appearance, if needed 293 lastpage.pageX = e.pageX; 294 lastpage.pageY = e.pageY; 295 }); 296 297 $tracker.one('mouseover', function(e){ 298 var $maginner=$magnifier.find('div:eq(0)') 299 var $bigimage=$('<img src="'+setting.largeimage+'"/>').appendTo($maginner) 300 var largeloaded = featuredimagezoomer.loaded[$('<a href="'+setting.largeimage+'"></a>').get(0).href]; 301 var showstatus=setting.zoomrange && setting.zoomrange[1]>setting.zoomrange[0] 302 var imgcoords=getcoords() 303 if(!largeloaded){ 304 $img.stop(true, true).css({opacity:0.1}) //"dim" image while large image is loading 305 $statusdiv.css({left:imgcoords.left+w/2-$statusdiv.width()/2, top:imgcoords.top+h/2-$statusdiv.height()/2, visibility:'visible'}) 306 } 307 $bigimage.bind('loadevt', function(event, e){ //magnified image ONLOAD event function (to be triggered later) 308 if(e.type === 'error'){ 309 $img.css({opacity: 1}).data('added').remove(); 310 var src = $('<a href="' + $bigimage.attr('src') + '"></a>').get(0).href; 311 if(window.console && console.error){ 312 console.error('Cannot find Featured Image Zoomer larger image: ' + src); 313 } else { 314 alert('Cannot find Featured Image Zoomer larger image:\n\n' + src); 315 } 316 return; 317 } 318 featuredimagezoomer.loaded[this.src] = true; 319 $img.css({opacity:1}) //restore thumb image opacity 320 $statusdiv.empty().css({border:'1px solid black', background:'#C0C0C0', padding:'4px', font:'bold 13px Arial', opacity:0.8}).hide().removeClass('preloadevt'); 321 if($tracker.data('premouseout')){ 322 $statusdiv.addClass('featuredimagezoomerhidden'); 323 } 324 if (setting.zoomrange){ //if set large image to a specific power 325 var nd=[w*setting.zoomrange[0], h*setting.zoomrange[0]] //calculate dimensions of new enlarged image 326 $bigimage.css({width:nd[0], height:nd[1]}) 327 } 328 getspecs($maginner, $bigimage) //remember various info about thumbnail and magnifier 329 $magnifier.css({display:'none', visibility:'visible'}) 330 $tracker.mouseover(function(e){ //image onmouseover 331 $tracker.data('specs').coords=getcoords() //refresh image coords (from upper left edge of document) 332 fiz.showimage($tracker, $magnifier, showstatus) 333 }) 334 $tracker.mousemove(function(e){ //image onmousemove
335 fiz.moveimage($tracker, $maginner, $cursorshade, e) 336 }) 337 if (!$tracker.data('premouseout')){ 338 fiz.showimage($tracker, $magnifier, showstatus); 339 fiz.moveimage($tracker, $maginner, $cursorshade, lastpage); 340 } 341 $tracker.mouseout(function(e){ //image onmouseout 342 fiz.hideimage($tracker, $magnifier, showstatus) 343 }).css({cursor: fiz.magnifycursor}); 344 if (setting.zoomrange && setting.zoomrange[1]>setting.zoomrange[0]){ //if zoom range enabled 345 $tracker.bind('DOMMouseScroll mousewheel', function(e){ 346 fiz.magnifyimage($tracker, e, setting.zoomrange); 347 e.preventDefault(); 348 }); 349 } else if(setting.disablewheel){ 350 $tracker.bind('DOMMouseScroll mousewheel', function(e){e.preventDefault();}); 351 } 352 }) //end $bigimage onload 353 if ($bigimage.get(0).complete){ //if image has already loaded (account for IE, Opera not firing onload event if so) 354 $bigimage.trigger('loadevt', {type: 'load'}) 355 } 356 else{ 357 $bigimage.bind('load error', function(e){$bigimage.trigger('loadevt', e)}) 358 } 359 }) 360 }, 361 362 iname: (function(){var itag = $('<img />'), iname = itag.get(0).tagName; itag.remove(); return iname;})(), 363 364 loaded: {}, 365 366 hashre: /^#/ 367 }); 368 369 $.fn.addimagezoom = function(options){ 370 var sel = this.selector, $thumbs = $(sel.replace(featuredimagezoomer.hashre, '.') + '.thumbs a'); 371 options = options || {}; 372 if(options.multizoom !== null && ($thumbs).size()){ 373 $thumbs.addmultizoom($.extend(options, {imgObj: sel, multizoom: null})); 374 return this; 375 } else if(options.multizoom){ 376 $(options.multizoom).addmultizoom($.extend(options, {imgObj: sel, multizoom: null})); 377 return this; 378 } else if (options.multizoom !== null){ 379 return this.each(function(){ 380 if (this.tagName !== featuredimagezoomer.iname) 381 return true; //skip to next matched element 382 $('<a href="' + this.src + '"></a>').addmultizoom($.extend(options, {imgObj: sel, multizoom: null, notmulti: true})); 383 }); 384 } 385 return this.each(function(){ //return jQuery obj 386 if (this.tagName !== featuredimagezoomer.iname) 387 return true; //skip to next matched element 388 featuredimagezoomer.init($(this), options); 389 }); 390 }; 391 392})(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.