1/** 2 * Author: Constantin Boiangiu (services[at]constantinb.com) 3 * Homepage: http://www.constantinb.com/project/jquery-image-zoom-zoomit/ 4 * Forum : http://www.constantinb.com/forums/forum/jquery-zoomit-plugin/ 5 * jQuery version: 1.6 6 * Copyright (c) author 7 * License: MIT (http://www.opensource.org/licenses/mit-license.php) 8 */ 9 10;(function($){ 11 12 $.fn.jqZoomIt = function(options){ 13 if (this.length > 1){ 14 this.each(function() { 15 $(this).jqZoomIt(options); 16 }); 17 return this; 18 } 19 20 var defaults = { 21 mouseEvent : 'mouseenter', // click, mouseenter, mouseover 22 zoomAreaMove : 'mousemove', // drag or mousemove 23 zoomPosition : 'right', // left, right, top, bottom 24 // CSS 25 zoomClass : 'zoomIt_zoomed', // additional styling on zoom container 26 zoomLoadingClass : 'zoomIt_loading', // css class to apply before the big image is fully loaded 27 zoomAreaClass : 'zoomIt_area', // additional styling on zoomed area 28 zoomAreaColor : '#FFF', // zoomed area bg color 29 30 zoomAreaOpacity : .5, // zoomed area opacity 31 zoomDistance : 50, // distance of the zoomer from the trigger 32 // full image multipliers based on small preview image size 33 multiplierX : 1, // how much of the big image width will be displayed 34 multiplierY : 0.8, // how much of the big image height will be displayed 35 // events 36 init : function(){}, 37 zoom : function(){}, 38 close : function(){}, 39 // conditional 40 is_touch : null // if left to null it will use an internal detection process. If bool, it will take the option and bypass internal functionality 41 }; 42 43 var options = $.extend({}, defaults, options), 44 self = this, 45 bigImg = $(this).attr('href'), 46 smallImg = $('img', this); 47 48 // if element doesn't have href attribute 49 // or small image isn't within main element, 50 // bail out 51 if( '' == bigImg || 0 == smallImg.length ){ 52 return false; 53 } 54 55 // start the plugin 56 var initialize = function(){ 57 58 // set the small image size 59 set_small_size(); 60 61 // prepare the preview wrapper element 62 add_preview_area(); 63 64 // add the events 65 var enterEvent = is_touch() ? 'touchstart' : ( 'click' == options.mouseEvent ? 'click' : 'mouseenter' ), 66 leaveEvent = is_touch() ? 'touchend' : 'mouseleave'; 67 68 $(self).bind( enterEvent, function(event){ 69 event.preventDefault(); 70 set_small_size(); 71 startZoom(); 72 options.zoom.call(self, {}); 73 }); 74 $(self).bind(leaveEvent, function(){ 75 closeZoom(); 76 options.close.call(self, {}); 77 }); 78 79 $(window).bind("resize", function(){ 80 set_small_size(); 81 $.data( self, 'loaded', false ); /*add*/ 82 fullImg=""; /*add*/ 83 }); 84 85 86 options.init.call(self, {}); 87 return self; 88 } 89 90 var startZoom = function(){ 91 92 var top_zoomed_img = $('.'+options.zoomClass+':visible img').css('top'); /*add*/ 93 var left_zoomed_img = $('.'+options.zoomClass+':visible img').css('left'); /*add*/ 94 95 96 97 var elems = get_preview_areas(), // returns object with keys zoomer and preview containing elements needed to create the zoom 98 sizes = get_small_size(); 99 100 $(elems.zoomer).stop(true, true).fadeIn('400').css({ 101 'top' : sizes.zTop, 102 'left' : sizes.zLeft, 103 'width' : sizes.width * ( options.multiplierX || 1 ), /*add*/ 104 'height' : sizes.height * ( options.multiplierY || 1 ) /*add*/ 105 }); 106 107 $(elems.zoomer).children('img').css({ /*add*/ 108 'top' : top_zoomed_img, /*add*/ 109 'left' : left_zoomed_img, /*add*/ 110 }); 111 112 113 // if no zoom is needed stop here 114 if( $.data( self, 'no_zoom') ){ 115 return; 116 } 117 118 // show and position preview area 119 120 /*$(elems.preview).show(); remove 121 if( $.data( self, 'loaded' ) ){ 122 return; 123 }*/ 124 125 if( $.data( self, 'loaded' ) ){ /*add 5 columns*/ 126 $(elems.preview).show(); 127 return; 128 } else { 129 $(elems.preview).css({'display': 'block', 'opacity': '0'}); 130 } 131 132 // add loading class to big image container
133 $( elems.zoomer ).addClass( options.zoomLoadingClass ); 134 // load the big image 135 136 var fullImg = $('<img />', { 137 'src' : bigImg 138 //}).load( function(){ 139 }).on('load', function(){ /* FOR JQUERY > 3 */ 140 // remove loader from zoom area 141 $( elems.zoomer ).removeClass( options.zoomLoadingClass ); 142 // inject full image 143 fullImg.css({ 144 'position' : 'absolute', 145 'top' : top_zoomed_img, /*add insted "0"*/ 146 'left' : left_zoomed_img, /*add insted "0"*/ 147 }).appendTo( $(elems.zoomer) ); 148 149 $.data( self, 'loaded', true ); 150 151 var fullWidth = fullImg.width(), 152 fullHeight = fullImg.height(), 153 ratioX = fullWidth / sizes.width, 154 ratioY = fullHeight / sizes.height, 155 dw = sizes.width / ratioX * ( options.multiplierX||1 ), 156 dh = sizes.height / ratioY * ( options.multiplierY||1 ); 157 158 159 // if image doesn't need zooming according to multiplier, set full img container size to image size 160 if( options.multiplierX > ratioX && options.multiplierY > ratioY ){ 161 $(elems.zoomer).css({ 162 'width' :fullWidth, 163 'height':fullHeight 164 }); 165 $.data( self, 'no_zoom', true ); 166 return; 167 } 168 169 if( 'drag' == options.zoomAreaMove && $.fn.draggable && !is_touch() ){ 170 // start drag 171 $(self).removeAttr('href'); 172 173 $(elems.preview).draggable({ 174 containment : 'parent', 175 drag: function(event, ui){ 176 var pos = $(elems.preview).position(), 177 left = -(pos.left * ratioX), 178 top = -(pos.top * ratioY); 179 fullImg.css({ 180 'left':left, 181 'top':top 182 }); 183 } 184 }) 185 186 }else{ 187 188 var moveEvent = is_touch() ? 'touchmove' : 'mousemove'; 189 190 $(self).bind( moveEvent, function( e ){ 191 // used to store current mouse position 192 var mouseX = 0, 193 mouseY = 0; 194 // get position on touch 195 if( is_touch() ){ 196 e.preventDefault(); 197 event = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 198 mouseX = event.pageX; 199 mouseY = event.pageY; 200 }else{ 201 // get position on non-touch 202 mouseX = e.pageX; 203 mouseY = e.pageY; 204 } 205 206 var sizes = get_small_size(), 207 mX = mouseX - sizes.left - dw/2, 208 mY = mouseY - sizes.top - dh/2; 209 210 // horizontal left limit 211 if( mouseX < sizes.left + dw/2 ){ 212 mX = 0; 213 } 214 // vertical top limit 215 if( mouseY < sizes.top + dh/2 ){ 216 mY = 0; 217 } 218 // horizontal right limit 219 if( mouseX > ( sizes.left + sizes.width - dw/2 )){ 220 mX = sizes.width - dw; 221 } 222 // vertical bottom limit 223 if( mouseY > ( sizes.top + sizes.height - dh/2 )){ 224 mY = sizes.height - dh; 225 } 226 227 // move zoomed area 228 $(elems.preview).css({ 229 'left':mX, 230 'top':mY 231 }); 232 233 // move full image 234 fullImg.css({ 235 'left' : -(mX * ratioX), 236 'top' : -(mY * ratioY) 237 }); 238 }) 239 } 240 241 // resize drag area that shows the position on small image 242 $(elems.preview).css({ 243 'width' : dw, 244 'height' : dh, 245 'opacity': options.zoomAreaOpacity || 0.7, /*add*/ 246 }); 247 }); 248 249 } 250 251 var closeZoom = function(){ 252 var elems = get_preview_areas(); 253 $(elems.zoomer).fadeOut('400', function(){ 254 $(this).css({ 255 'top' : -5000, 256 'left': -5000 257 }); 258 }); 259 $(elems.preview).hide(); 260 } 261 262 // set small image size 263 var set_small_size = function(){ 264 265 var position = $(smallImg[0]).offset(), 266 data = { 267 'width' : $(smallImg[0]).outerWidth(), 268 'height' : $(smallImg[0]).outerHeight(), 269 'top' : position.top, 270 'left' : position.left, 271 'zTop' : position.top, 272 'zLeft' : position.left 273 }; 274 // make some position calculations based on position option 275 276 277 var coordsX = $('.product_detail_title').offset().left; //--custom 278 279 switch( options.zoomPosition ){
280 case 'right': 281 default: 282 // data.zLeft += data.width + options.zoomDistance; //--default 283 data.zLeft = coordsX; //--custom 284 break; 285 case 'left': 286 // data.zLeft -= data.width * ( options.multiplierX || 1 ) + options.zoomDistance; //--default 287 288 data.zLeft = coordsX; //--custom 289 break; 290 case 'bottom': 291 data.zTop += data.height + options.zoomDistance; 292 break; 293 case 'top': 294 data.zTop -= data.height * ( options.multiplierY || 1 ) + options.zoomDistance; 295 break; 296 } 297 298 299 $.data( smallImg[0], 'size', data ); 300 return data; 301 } 302 303 // helper function to get small image size stored on element 304 var get_small_size = function(){ 305 return $.data( smallImg[0], 'size' ); 306 } 307 308 // creates an element that overlaps the image to highlight the area being zoomed 309 var add_preview_area = function(){ 310 var dragger = $('<div />',{ 311 'class': options.zoomAreaClass, 312 'css':{ 313 'background-color' : options.zoomAreaColor || '#999', 314 'opacity' : options.zoomAreaOpacity || .7, 315 'display' : 'none', 316 'position' : 'absolute', 317 'top' : 0, 318 'left' : 0, 319 'cursor' : 'move', 320 'z-index' : 10000 321 } 322 }).appendTo( $(self) ); 323 324 var sizes = get_small_size(); 325 326 var zoomer = $('<div />', { 327 'class' : options.zoomClass, 328 'css' :{ 329 'display' : 'none', 330 'position' : 'absolute', 331 'top' : -1000, 332 'overflow' : 'hidden', 333 'width' : sizes.width * ( options.multiplierX || 1 ), 334 'height' : sizes.height * ( options.multiplierY || 1 ), 335 'z-index' : 100 336 } 337 }).appendTo( $(document.body) ); 338 339 var data = { 340 'zoomer' : zoomer, 341 'preview' : dragger 342 }; 343 $.data( smallImg[0], 'elems', data ); 344 } 345 346 // helper function to return element that highlights the zoomed area 347 var get_preview_areas = function(){ 348 return $.data( smallImg[0], 'elems'); 349 } 350 351 /** 352 * Verifies if browser has touch capabilities. Testing isn't bullet proof, you're encouraged 353 * to override the functionality by setting the parameter is_touch in options to a value determined 354 * by a third-party, more comprehensive browser testing script. 355 */ 356 var is_touch = function(){ 357 if( options.is_touch !== null ){ 358 return options.is_touch; 359 } 360 return /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); 361 } 362 363 return initialize(); 364 } 365})(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.