diff --git a/README.md b/README.md index 0c07a61..64c4b6a 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,10 @@ This work is licensed under a [MIT License][5]. This jQuery plugin was written by [Matt Hinchliffe][6]. +Thanks also for contributions from: + +- [Steve Lindstrom](https://github.com/slindstr) + [1]: http://github.com/i-like-robots/EasyZoom/ [2]: http://www.jquery.com [3]: http://cssglobe.com/lab/easyzoom/easyzoom.html diff --git a/bower.json b/bower.json index 090ce19..ac8c8a7 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "easyzoom", - "version": "2.2.0", + "version": "2.2.1", "description": "EasyZoom is an elegant, highly optimised jQuery image zoom and panning plugin based on the original work by Alen Grakalic. EasyZoom supports touch-enabled devices and is easily customisable with CSS.", "keywords": [ "zoom", diff --git a/dist/easyzoom.js b/dist/easyzoom.js index 6f3355e..cd83a52 100644 --- a/dist/easyzoom.js +++ b/dist/easyzoom.js @@ -1,6 +1,6 @@ /*! * @name image-zoom * @author Matt Hinchliffe - * @modified Tuesday, July 15th, 2014 - * @version 2.2.0 - */!function(a){"use strict";function b(b,c){return this.$target=a(b),this.opts=a.extend({},i,c),void 0===this.isOpen&&this._init(),this}var c,d,e,f,g,h,i={loadingNotice:"Loading image",errorNotice:"The image could not be loaded",errorDuration:2500,preventClicks:!0,onShow:void 0,onHide:void 0};b.prototype._init=function(){var b=this;this.$link=this.$target.find("a"),this.$image=this.$target.find("img"),this.$flyout=a('
'),this.$notice=a('
'),this.$target.on("mouseenter.easyzoom touchstart.easyzoom",function(a){b.isMouseOver=!0,a.originalEvent.touches&&1!==a.originalEvent.touches.length||(a.preventDefault(),b.show(a,!0))}).on("mousemove.easyzoom touchmove.easyzoom",function(a){b.isOpen&&(a.preventDefault(),b._move(a))}).on("mouseleave.easyzoom touchend.easyzoom",function(){b.isMouseOver=!1,b.isOpen&&b.hide()}),this.opts.preventClicks&&this.$target.on("click.easyzoom","a",function(a){a.preventDefault()})},b.prototype.show=function(a,b){var g,h,i,j,k=this;return this.isReady?(this.$target.append(this.$flyout),g=this.$target.width(),h=this.$target.height(),i=this.$flyout.width(),j=this.$flyout.height(),c=this.$zoom.width()-i,d=this.$zoom.height()-j,e=c/g,f=d/h,this.isOpen=!0,this.opts.onShow&&this.opts.onShow.call(this),void(a&&this._move(a))):void this._load(this.$link.attr("href"),function(){(!b||k.isMouseOver)&&k.show(a)})},b.prototype._load=function(b,c){var d=new Image;this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)),this.$zoom=a(d),d.onerror=a.proxy(function(){var a=this;this.$notice.text(this.opts.errorNotice),this.$target.removeClass("is-loading").addClass("is-error"),this.detachNotice=setTimeout(function(){a.$notice.detach(),a.detachNotice=null},this.opts.errorDuration)},this),d.onload=a.proxy(function(){0!==d.width&&(this.isReady=!0,this.$notice.detach(),this.$flyout.html(this.$zoom),this.$target.removeClass("is-loading").addClass("is-ready"),c())},this),d.style.position="absolute",d.src=b},b.prototype._move=function(a){if(0===a.type.indexOf("touch")){var b=a.touches||a.originalEvent.touches;g=b[0].pageX,h=b[0].pageY}else g=a.pageX||g,h=a.pageY||h;var i=this.$target.offset(),j=h-i.top,k=g-i.left,l=j*f,m=k*e;0>m||0>l||m>c||l>d?this.hide():this.$zoom.css({top:""+-1*Math.ceil(l)+"px",left:""+-1*Math.ceil(m)+"px"})},b.prototype.hide=function(){this.isOpen&&(this.$flyout.detach(),this.isOpen=!1,this.opts.onHide&&this.opts.onHide.call(this))},b.prototype.swap=function(a,b){this.hide(),this.isReady=!1,this.detachNotice&&clearTimeout(this.detachNotice),this.$notice.parent().length&&this.$notice.detach(),this.$target.removeClass("is-loading is-ready is-error"),this.$image.attr("src",a),this.$link.attr("href",b)},b.prototype.teardown=function(){this.hide(),this.$target.removeClass("is-loading is-ready is-error").off(".easyzoom"),this.detachNotice&&clearTimeout(this.detachNotice),delete this.$link,delete this.$zoom,delete this.$image,delete this.$notice,delete this.$flyout,delete this.isOpen,delete this.isReady},a.fn.easyZoom=function(c){return this.each(function(){var d=a.data(this,"easyZoom");d?void 0===d.isOpen&&d._init():a.data(this,"easyZoom",new b(this,c))})},"function"==typeof define&&define.amd?define(function(){return b}):"undefined"!=typeof module&&module.exports&&(module.exports=b)}(jQuery); \ No newline at end of file + * @modified Monday, September 15th, 2014 + * @version 2.2.1 + */!function(a){"use strict";function b(b,c){return this.$target=a(b),this.opts=a.extend({},i,c),void 0===this.isOpen&&this._init(),this}var c,d,e,f,g,h,i={loadingNotice:"Loading image",errorNotice:"The image could not be loaded",errorDuration:2500,preventClicks:!0,onShow:void 0,onHide:void 0};b.prototype._init=function(){var b=this;this.$link=this.$target.find("a"),this.$image=this.$target.find("img"),this.$flyout=a('
'),this.$notice=a('
'),this.$target.on("mouseenter.easyzoom touchstart.easyzoom",function(a){b.isMouseOver=!0,a.originalEvent.touches&&1!==a.originalEvent.touches.length||(a.preventDefault(),b.show(a,!0))}).on("mousemove.easyzoom touchmove.easyzoom",function(a){b.isOpen&&(a.preventDefault(),b._move(a))}).on("mouseleave.easyzoom touchend.easyzoom",function(){b.isMouseOver=!1,b.isOpen&&b.hide()}),this.opts.preventClicks&&this.$target.on("click.easyzoom","a",function(a){a.preventDefault()})},b.prototype.show=function(a,b){var g,h,i,j,k=this;return this.isReady?(this.$target.append(this.$flyout),g=this.$target.width(),h=this.$target.height(),i=this.$flyout.width(),j=this.$flyout.height(),c=this.$zoom.width()-i,d=this.$zoom.height()-j,e=c/g,f=d/h,this.isOpen=!0,this.opts.onShow&&this.opts.onShow.call(this),void(a&&this._move(a))):void this._load(this.$link.attr("href"),function(){(k.isMouseOver||!b)&&k.show(a)})},b.prototype._load=function(b,c){var d=new Image;this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)),this.$zoom=a(d),d.onerror=a.proxy(function(){var a=this;this.$notice.text(this.opts.errorNotice),this.$target.removeClass("is-loading").addClass("is-error"),this.detachNotice=setTimeout(function(){a.$notice.detach(),a.detachNotice=null},this.opts.errorDuration)},this),d.onload=a.proxy(function(){d.width&&(this.isReady=!0,this.$notice.detach(),this.$flyout.html(this.$zoom),this.$target.removeClass("is-loading").addClass("is-ready"),c())},this),d.style.position="absolute",d.src=b},b.prototype._move=function(a){if(0===a.type.indexOf("touch")){var b=a.touches||a.originalEvent.touches;g=b[0].pageX,h=b[0].pageY}else g=a.pageX||g,h=a.pageY||h;var i=this.$target.offset(),j=h-i.top,k=g-i.left,l=Math.ceil(j*f),m=Math.ceil(k*e);0>m||0>l||m>c||l>d?this.hide():this.$zoom.css({top:""+-1*l+"px",left:""+-1*m+"px"})},b.prototype.hide=function(){this.isOpen&&(this.$flyout.detach(),this.isOpen=!1,this.opts.onHide&&this.opts.onHide.call(this))},b.prototype.swap=function(b,c,d){this.hide(),this.isReady=!1,this.detachNotice&&clearTimeout(this.detachNotice),this.$notice.parent().length&&this.$notice.detach(),a.isArray(d)&&(d=d.join()),this.$target.removeClass("is-loading is-ready is-error"),this.$image.attr({src:b,srcset:d}),this.$link.attr("href",c)},b.prototype.teardown=function(){this.hide(),this.$target.removeClass("is-loading is-ready is-error").off(".easyzoom"),this.detachNotice&&clearTimeout(this.detachNotice),delete this.$link,delete this.$zoom,delete this.$image,delete this.$notice,delete this.$flyout,delete this.isOpen,delete this.isReady},a.fn.easyZoom=function(c){return this.each(function(){var d=a.data(this,"easyZoom");d?void 0===d.isOpen&&d._init():a.data(this,"easyZoom",new b(this,c))})},"function"==typeof define&&define.amd?define(function(){return b}):"undefined"!=typeof module&&module.exports&&(module.exports=b)}(jQuery); \ No newline at end of file diff --git a/image-zoom.jquery.json b/image-zoom.jquery.json index a05be17..feab3ce 100644 --- a/image-zoom.jquery.json +++ b/image-zoom.jquery.json @@ -1,6 +1,6 @@ { "name": "image-zoom", - "version": "2.2.0", + "version": "2.2.1", "title": "EasyZoom, jQuery image zoom plugin", "description": "EasyZoom is an elegant, highly optimised jQuery image zoom and panning plugin based on the original work by Alen Grakalic. EasyZoom supports touch-enabled devices and is easily customisable with CSS.", "keywords": [ diff --git a/index.html b/index.html index 4a285de..67c93d4 100644 --- a/index.html +++ b/index.html @@ -273,10 +273,10 @@

Removes all events and elements created and attached by EasyZoom.
- .swap(standardSrc, zoomSrc) + .swap(standardSrc, zoomSrc, [srcsetStringOrArray])
- Easily switch the standard and zoom image sources. + Easily switch the standard and zoom image sources. To display retina images via the srcset attribute, use the optional srcsetStringOrArray argument.
diff --git a/package.json b/package.json index bc9ab92..54c8d53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "EasyZoom", - "version": "2.2.0", + "version": "2.2.1", "devDependencies": { "grunt": "0.4.x", "grunt-contrib-jshint": "0.9.x", diff --git a/src/easyzoom.js b/src/easyzoom.js index 0e70c0e..c1e978c 100644 --- a/src/easyzoom.js +++ b/src/easyzoom.js @@ -36,7 +36,7 @@ this.$target = $(target); this.opts = $.extend({}, defaults, options); - if ( this.isOpen === undefined ) { + if (this.isOpen === undefined) { this._init(); } @@ -60,7 +60,7 @@ .on('mouseenter.easyzoom touchstart.easyzoom', function(e) { self.isMouseOver = true; - if ( ! e.originalEvent.touches || e.originalEvent.touches.length === 1) { + if (!e.originalEvent.touches || e.originalEvent.touches.length === 1) { e.preventDefault(); self.show(e, true); } @@ -97,7 +97,7 @@ if (! this.isReady) { this._load(this.$link.attr('href'), function() { - if (!testMouseOver || self.isMouseOver) { + if (self.isMouseOver || !testMouseOver) { self.show(e); } }); @@ -158,7 +158,7 @@ zoom.onload = $.proxy(function() { // IE may fire a load event even on error so check the image has dimensions - if (zoom.width === 0) { + if (!zoom.width) { return; } @@ -195,8 +195,8 @@ var offset = this.$target.offset(); var pt = ly - offset.top; var pl = lx - offset.left; - var xt = pt * rh; - var xl = pl * rw; + var xt = Math.ceil(pt * rh); + var xl = Math.ceil(pl * rw); // Close if outside if (xl < 0 || xt < 0 || xl > dw || xt > dh) { @@ -204,8 +204,8 @@ } else { this.$zoom.css({ - top: '' + (Math.ceil(xt) * -1) + 'px', - left: '' + (Math.ceil(xl) * -1) + 'px' + top: '' + (xt * -1) + 'px', + left: '' + (xl * -1) + 'px' }); } @@ -229,8 +229,9 @@ * Swap * @param {String} standardSrc * @param {String} zoomHref + * @param {String|Array} srcsetStringOrArray (Optional) */ - EasyZoom.prototype.swap = function(standardSrc, zoomHref) { + EasyZoom.prototype.swap = function(standardSrc, zoomHref, srcsetStringOrArray) { this.hide(); this.isReady = false; @@ -242,8 +243,15 @@ this.$notice.detach(); } + if ($.isArray(srcsetStringOrArray)) { + srcsetStringOrArray = srcsetStringOrArray.join(); + } + this.$target.removeClass('is-loading is-ready is-error'); - this.$image.attr('src', standardSrc); + this.$image.attr({ + src: standardSrc, + srcset: srcsetStringOrArray + }); this.$link.attr('href', zoomHref); }; @@ -270,26 +278,26 @@ }; // jQuery plugin wrapper - $.fn.easyZoom = function( options ) { + $.fn.easyZoom = function(options) { return this.each(function() { var api = $.data(this, 'easyZoom'); - if ( ! api) { + if (!api) { $.data(this, 'easyZoom', new EasyZoom(this, options)); } - else if ( api.isOpen === undefined ) { + else if (api.isOpen === undefined) { api._init(); } }); }; // AMD and CommonJS module compatibility - if ( typeof define === 'function' && define.amd ){ + if (typeof define === 'function' && define.amd){ define(function() { return EasyZoom; }); } - else if ( typeof module !== 'undefined' && module.exports ) { + else if (typeof module !== 'undefined' && module.exports) { module.exports = EasyZoom; } diff --git a/test/spec/easyzoom.js b/test/spec/easyzoom.js index 789ec3b..798b153 100644 --- a/test/spec/easyzoom.js +++ b/test/spec/easyzoom.js @@ -127,6 +127,35 @@ }); + test(".swap(standard, zoom, srcsetString)", function() { + + expect(1); + + var standard = "../example-images/test_standard.jpg"; + var zoom = "../example-images/test_zoom.jpg"; + var srcsetString = "../example-images/test_standard.jpg 1x, ../example-images/test_zoom.jpg 2x"; + + api.swap(standard, zoom, srcsetString); + + equal(api.$image.attr("srcset"), srcsetString, "Standard image SRCSET changed"); + + }); + + test(".swap(standard, zoom, srcsetArray)", function() { + + expect(1); + + var standard = "../example-images/test_standard.jpg"; + var zoom = "../example-images/test_zoom.jpg"; + var srcsetArray = ['../example-images/test_standard.jpg 1x', '../example-images/test_zoom.jpg 2x']; + var srcsetString = '../example-images/test_standard.jpg 1x,../example-images/test_zoom.jpg 2x'; + + api.swap(standard, zoom, srcsetArray); + + equal(api.$image.attr("srcset"), srcsetString, "Standard image SRCSET changed"); + + }); + test(".teardown()", function() { api.teardown();