﻿(function ($) { $.imgZoom = function (img, options) { var svgns = "http://www.w3.org/2000/svg", width, height, thumbWidth, thumbHeight, src, image, imgOfs, endX, endY, $bigImg = $('<img/>'), Z = $.imgZoom, M = Math, imgZoom = this, winWidth, winHeight, time, fx = $.extend($('<div/>')[0], { imgZoom: this, pos: 0 }); function setOptions(newOptions) { if (!Z.loaded) return $(window).load(function () { setOptions(newOptions) }); options = $.extend(options, newOptions); $('<img/>').attr('src', options.loadingImg); Z.$loading.css({ backgroundImage: 'url(' + options.loadingImg + ')', backgroundPosition: 'center', backgroundRepeat: 'no-repeat' }) } function getImgOfs() { imgOfs = { left: M.round($(img).offset().left + ($(img).outerWidth() - thumbWidth) / 2), top: M.round($(img).offset().top + ($(img).outerHeight() - thumbHeight) / 2)} } function reset() { winWidth = $(window).width(); winHeight = $.browser.opera && $.browser.version < 9.5 ? window.innerHeight : $(window).height(); getImgOfs(); Z.$overlay.css({ backgroundColor: options.showOverlay ? '#000' : '', position: 'absolute', left: 0, top: 0, width: M.max(winWidth, document.documentElement.scrollWidth), height: M.max(winHeight, document.documentElement.scrollHeight), overflow: 'hidden' }); if (Z.svg) { Z.svg.setAttribute('width', Z.$overlay.width()); Z.svg.setAttribute('height', Z.$overlay.height()) } else { $(Z.vmlGroup).css({ width: Z.$overlay.width(), height: Z.$overlay.height() }); Z.vmlGroup.coordsize = Z.$overlay.width() + ',' + Z.$overlay.height() } } function animate(pos) { var w = M.round(thumbWidth + (width - thumbWidth) * pos), h = M.round(thumbHeight + (height - thumbHeight) * pos), angle = M.round(pos * parseInt(options.rotate + 0) * 360), opacity = $.isArray(options.opacity) ? options.opacity[0] * (1 - pos) + pos * options.opacity[1] : options.opacity * (1 - pos) + pos, overlayOpacity = pos * options.overlayOpacity; fx.pos = pos; getImgOfs(); var x = M.round(imgOfs.left * (1 - pos) + endX * pos), y = M.round(imgOfs.top * (1 - pos) + endY * pos); if (options.showOverlay) Z.$overlay.css('opacity', overlayOpacity); if (Z.svg) { image.setAttribute('width', w); image.setAttribute('height', h); image.setAttribute('x', x); image.setAttribute('y', y); if (options.rotate) image.setAttribute('transform', 'rotate(' + angle + ',' + M.round(x + w / 2) + ', ' + M.round(y + h / 2) + ')'); $(image).css('opacity', opacity); if ($.browser.safari) { var rect = document.createElementNS(svgns, "rect"); rect.setAttribute('x', -Z.$overlay.width()); rect.setAttribute('y', -Z.$overlay.height()); rect.setAttribute('width', 3 * Z.$overlay.width()); rect.setAttribute('height', 3 * Z.$overlay.height()); rect.setAttribute('fill', 'none'); $(Z.svg).append(rect); setTimeout(function () { $(rect).remove() }, 0) } } else { $(image).css({ width: w, height: h, left: x, top: y, opacity: opacity }); if (options.rotate) image.style.rotation = angle } } function zoom(duration, callback, out) { if (isNaN(duration)) duration = options.duration; Z.animating++; if (!out) { Z.$anim.show(); endX = M.round((winWidth - width) / 2 + $(document).scrollLeft()); endY = M.round((winHeight - height) / 2 + $(document).scrollTop()); if (options.hideThumbnail) $(img).css('visibility', 'hidden'); if (Z.svg) { image.setAttributeNS("http://www.w3.org/1999/xlink", "href", src); $(Z.svg).append(image) } else { $(image).css('z-index', 1000) } } reset(); $(image).show(); $(fx).animate({ pos: out ? 0 : 1 }, duration, 'swing', function () { if (!out) $bigImg.css({ left: endX, top: endY, opacity: $.isArray(options.opacity) ? options.opacity[1] : 1 }).click(function () { Z.$anim.show(); $bigImg.remove(); zoomOut() }).appendTo('body').show(); else $(img).css('visibility', ''); $(image).css('z-index', '').hide(); Z.animating--; if ((!options.showOverlay || out) && !Z.animating) Z.$anim.hide(); if (callback) callback.call() }) }; function doZoomIn(duration, callback) { if (Z.zoomed) Z.zoomed.zoomOut(); zoom(duration, callback); Z.zoomed = imgZoom } function zoomIn(duration, callback) { if (Z.animating || Z.zoomed == imgZoom) return; if (width != null) doZoomIn(duration, callback); else { Z.$loading.css({ position: 'absolute', left: imgOfs.left, top: imgOfs.top, width: thumbWidth, height: thumbHeight }).appendTo('body').show(); time = (new Date()).getTime(); $bigImg.one('load', function () { $bigImg.hide().appendTo('body'); width = $bigImg.width(); height = $bigImg.height(); time = (new Date()).getTime() - time; if (Z.svg) { Z.$loading.hide(); doZoomIn(duration, callback) } else { image.src = src; setTimeout(function () { Z.$loading.hide(); doZoomIn(duration, callback) }, time * 2 + 50) } }).attr('src', src).css('position', 'absolute') } } function zoomOut(duration, callback) { if (Z.animating || Z.zoomed != imgZoom) return; Z.$anim.show(); $bigImg.remove(); zoom(duration, callback, true); if (Z.zoomed == imgZoom) Z.zoomed = null } function init() { if (!Z.$overlay) { Z.$overlay = $('<div/>'); Z.$loading = $('<div/>') } setOptions(options = $.extend({ duration: 500, loadingImg: 'css/loading.gif', opacity: 1, overlayOpacity: .75 }, options)); src = options.src || $(img).parent().attr('href'); thumbWidth = img.clientWidth; thumbHeight = img.clientHeight; if (window.SVGAngle) { if (!Z.svg) { $(Z.svg = document.createElementNS(svgns, "svg")).css({ position: 'absolute', left: 0, top: 0 }); Z.$anim = Z.$overlay.add($(Z.svg)) } $(image = document.createElementNS(svgns, "image")).hide(); $(Z.svg).append(image) } else { if (!Z.vmlGroup) { document.createStyleSheet().addRule(".imgzoom-vml", "behavior:url(#default#VML)"); if (!document.namespaces.izvml) document.namespaces.add("izvml", "urn:schemas-microsoft-com:vml"); Z.vmlElem = function (tagName) { return document.createElement('<izvml:' + tagName + ' class="imgzoom-vml">') }; $(Z.vmlGroup = Z.vmlElem('group')).css({ position: 'absolute', left: 0, top: 0 }); Z.$anim = Z.$overlay.add($(Z.vmlGroup)) } $(image = Z.vmlElem('image')).hide(); $(Z.vmlGroup).append(image) } Z.$anim.hide().appendTo('body'); reset(); $(img).click(function () { if (!Z.animating) if (Z.zoomed == imgZoom) zoomOut(); else zoomIn(); return false }); if (!Z.fxStepDefault) { Z.fxStepDefault = $.fx.step._default; $.fx.step._default = function (fx) { return fx.elem.imgZoom ? fx.elem.imgZoom.animate(fx.now) : Z.fxStepDefault(fx) } } $(window).resize(reset) } this.getOptions = function () { return options }; this.setOptions = setOptions; this.animate = animate; this.zoomIn = zoomIn; this.zoomOut = zoomOut; this.init = init; if (Z.loaded) init(); else $(window).load(this.init) }; $.imgZoom.animating = 0; $(window).load(function () { $.imgZoom.loaded = true }); $.fn.imgZoom = function (options) { options = options || {}; this.filter('img').each(function () { if ($(this).data('imgZoom')) $(this).data('imgZoom').setOptions(options); else $(this).data('imgZoom', new $.imgZoom(this, options)) }); if (options.instance) return $(this).filter('img').data('imgZoom'); return this } })(jQuery);
