zoom.min.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*!
  2. Zoom 1.7.21
  3. license: MIT
  4. http://www.jacklmoore.com/zoom
  5. */
  6. (function ($) {
  7. var defaults = {
  8. url: false,
  9. callback: false,
  10. target: false,
  11. duration: 120,
  12. on: 'mouseover', // other options: grab, click, toggle
  13. touch: true, // enables a touch fallback
  14. onZoomIn: false,
  15. onZoomOut: false,
  16. magnify: 1
  17. };
  18. // Core Zoom Logic, independent of event listeners.
  19. $.zoom = function(target, source, img, magnify) {
  20. var targetHeight,
  21. targetWidth,
  22. sourceHeight,
  23. sourceWidth,
  24. xRatio,
  25. yRatio,
  26. offset,
  27. $target = $(target),
  28. position = $target.css('position'),
  29. $source = $(source);
  30. // The parent element needs positioning so that the zoomed element can be correctly positioned within.
  31. target.style.position = /(absolute|fixed)/.test(position) ? position : 'relative';
  32. target.style.overflow = 'hidden';
  33. img.style.width = img.style.height = '';
  34. $(img)
  35. .addClass('zoomImg')
  36. .css({
  37. position: 'absolute',
  38. top: 0,
  39. left: 0,
  40. opacity: 0,
  41. width: img.width * magnify,
  42. height: img.height * magnify,
  43. border: 'none',
  44. maxWidth: 'none',
  45. maxHeight: 'none'
  46. })
  47. .appendTo(target);
  48. return {
  49. init: function() {
  50. targetWidth = $target.outerWidth();
  51. targetHeight = $target.outerHeight();
  52. if (source === target) {
  53. sourceWidth = targetWidth;
  54. sourceHeight = targetHeight;
  55. } else {
  56. sourceWidth = $source.outerWidth();
  57. sourceHeight = $source.outerHeight();
  58. }
  59. xRatio = (img.width - targetWidth) / sourceWidth;
  60. yRatio = (img.height - targetHeight) / sourceHeight;
  61. offset = $source.offset();
  62. },
  63. move: function (e) {
  64. var left = (e.pageX - offset.left),
  65. top = (e.pageY - offset.top);
  66. top = Math.max(Math.min(top, sourceHeight), 0);
  67. left = Math.max(Math.min(left, sourceWidth), 0);
  68. img.style.left = (left * -xRatio) + 'px';
  69. img.style.top = (top * -yRatio) + 'px';
  70. }
  71. };
  72. };
  73. $.fn.zoom = function (options) {
  74. return this.each(function () {
  75. var
  76. settings = $.extend({}, defaults, options || {}),
  77. //target will display the zoomed image
  78. target = settings.target && $(settings.target)[0] || this,
  79. //source will provide zoom location info (thumbnail)
  80. source = this,
  81. $source = $(source),
  82. img = document.createElement('img'),
  83. $img = $(img),
  84. mousemove = 'mousemove.zoom',
  85. clicked = false,
  86. touched = false;
  87. // If a url wasn't specified, look for an image element.
  88. if (!settings.url) {
  89. var srcElement = source.querySelector('img');
  90. if (srcElement) {
  91. settings.url = srcElement.getAttribute('data-src') || srcElement.currentSrc || srcElement.src;
  92. }
  93. if (!settings.url) {
  94. return;
  95. }
  96. }
  97. $source.one('zoom.destroy', function(position, overflow){
  98. $source.off(".zoom");
  99. target.style.position = position;
  100. target.style.overflow = overflow;
  101. img.onload = null;
  102. $img.remove();
  103. }.bind(this, target.style.position, target.style.overflow));
  104. img.onload = function () {
  105. var zoom = $.zoom(target, source, img, settings.magnify);
  106. function start(e) {
  107. zoom.init();
  108. zoom.move(e);
  109. // Skip the fade-in for IE8 and lower since it chokes on fading-in
  110. // and changing position based on mousemovement at the same time.
  111. $img.stop()
  112. .fadeTo($.support.opacity ? settings.duration : 0, 1, $.isFunction(settings.onZoomIn) ? settings.onZoomIn.call(img) : false);
  113. }
  114. function stop() {
  115. $img.stop()
  116. .fadeTo(settings.duration, 0, $.isFunction(settings.onZoomOut) ? settings.onZoomOut.call(img) : false);
  117. }
  118. // Mouse events
  119. if (settings.on === 'grab') {
  120. $source
  121. .on('mousedown.zoom',
  122. function (e) {
  123. if (e.which === 1) {
  124. $(document).one('mouseup.zoom',
  125. function () {
  126. stop();
  127. $(document).off(mousemove, zoom.move);
  128. }
  129. );
  130. start(e);
  131. $(document).on(mousemove, zoom.move);
  132. e.preventDefault();
  133. }
  134. }
  135. );
  136. } else if (settings.on === 'click') {
  137. $source.on('click.zoom',
  138. function (e) {
  139. if (clicked) {
  140. // bubble the event up to the document to trigger the unbind.
  141. return;
  142. } else {
  143. clicked = true;
  144. start(e);
  145. $(document).on(mousemove, zoom.move);
  146. $(document).one('click.zoom',
  147. function () {
  148. stop();
  149. clicked = false;
  150. $(document).off(mousemove, zoom.move);
  151. }
  152. );
  153. return false;
  154. }
  155. }
  156. );
  157. } else if (settings.on === 'toggle') {
  158. $source.on('click.zoom',
  159. function (e) {
  160. if (clicked) {
  161. stop();
  162. } else {
  163. start(e);
  164. }
  165. clicked = !clicked;
  166. }
  167. );
  168. } else if (settings.on === 'mouseover') {
  169. zoom.init(); // Preemptively call init because IE7 will fire the mousemove handler before the hover handler.
  170. $source
  171. .on('mouseenter.zoom', start)
  172. .on('mouseleave.zoom', stop)
  173. .on(mousemove, zoom.move);
  174. }
  175. // Touch fallback
  176. if (settings.touch) {
  177. $source
  178. .on('touchstart.zoom', function (e) {
  179. e.preventDefault();
  180. if (touched) {
  181. touched = false;
  182. stop();
  183. } else {
  184. touched = true;
  185. start( e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] );
  186. }
  187. })
  188. .on('touchmove.zoom', function (e) {
  189. e.preventDefault();
  190. zoom.move( e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] );
  191. })
  192. .on('touchend.zoom', function (e) {
  193. e.preventDefault();
  194. if (touched) {
  195. touched = false;
  196. stop();
  197. }
  198. });
  199. }
  200. if ($.isFunction(settings.callback)) {
  201. settings.callback.call(img);
  202. }
  203. };
  204. img.setAttribute('role', 'presentation');
  205. img.alt = '';
  206. img.src = settings.url;
  207. });
  208. };
  209. $.fn.zoom.defaults = defaults;
  210. }(window.jQuery));