1
0

wheelzoom.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*!
  2. Wheelzoom 4.0.1
  3. license: MIT
  4. http://www.jacklmoore.com/wheelzoom
  5. */
  6. window.wheelzoom = (function(){
  7. var defaults = {
  8. zoom: 0.10,
  9. maxZoom: false,
  10. initialZoom: 1,
  11. initialX: 0.5,
  12. initialY: 0.5,
  13. };
  14. var main = function(img, options){
  15. if (!img || !img.nodeName || img.nodeName !== 'IMG') { return; }
  16. var settings = {};
  17. var width;
  18. var height;
  19. var bgWidth;
  20. var bgHeight;
  21. var bgPosX;
  22. var bgPosY;
  23. var previousEvent;
  24. var transparentSpaceFiller;
  25. function setSrcToBackground(img) {
  26. img.style.backgroundRepeat = 'no-repeat';
  27. img.style.backgroundImage = 'url("'+img.src+'")';
  28. transparentSpaceFiller = 'data:image/svg+xml;base64,'+window.btoa('<svg xmlns="http://www.w3.org/2000/svg" width="'+img.naturalWidth+'" height="'+img.naturalHeight+'"></svg>');
  29. img.src = transparentSpaceFiller;
  30. }
  31. function updateBgStyle() {
  32. if (bgPosX > 0) {
  33. bgPosX = 0;
  34. } else if (bgPosX < width - bgWidth) {
  35. bgPosX = width - bgWidth;
  36. }
  37. if (bgPosY > 0) {
  38. bgPosY = 0;
  39. } else if (bgPosY < height - bgHeight) {
  40. bgPosY = height - bgHeight;
  41. }
  42. img.style.backgroundSize = bgWidth+'px '+bgHeight+'px';
  43. img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px';
  44. /*var lol = img.style.width;
  45. var lol2 = lol + 200;
  46. img.style.width = lol2+'px';*/
  47. }
  48. function reset() {
  49. bgWidth = width;
  50. bgHeight = height;
  51. bgPosX = bgPosY = 0;
  52. updateBgStyle();
  53. }
  54. function onwheel(e) {
  55. var deltaY = 0;
  56. e.preventDefault();
  57. if (e.deltaY) { // FireFox 17+ (IE9+, Chrome 31+?)
  58. deltaY = e.deltaY;
  59. } else if (e.wheelDelta) {
  60. deltaY = -e.wheelDelta;
  61. }
  62. // As far as I know, there is no good cross-browser way to get the cursor position relative to the event target.
  63. // We have to calculate the target element's position relative to the document, and subtrack that from the
  64. // cursor's position relative to the document.
  65. var rect = img.getBoundingClientRect();
  66. var offsetX = e.pageX - rect.left - window.pageXOffset;
  67. var offsetY = e.pageY - rect.top - window.pageYOffset;
  68. // Record the offset between the bg edge and cursor:
  69. var bgCursorX = offsetX - bgPosX;
  70. var bgCursorY = offsetY - bgPosY;
  71. // Use the previous offset to get the percent offset between the bg edge and cursor:
  72. var bgRatioX = bgCursorX/bgWidth;
  73. var bgRatioY = bgCursorY/bgHeight;
  74. // Update the bg size:
  75. if (deltaY < 0) {
  76. bgWidth += bgWidth*settings.zoom;
  77. bgHeight += bgHeight*settings.zoom;
  78. } else {
  79. bgWidth -= bgWidth*settings.zoom;
  80. bgHeight -= bgHeight*settings.zoom;
  81. }
  82. if (settings.maxZoom) {
  83. bgWidth = Math.min(width*settings.maxZoom, bgWidth);
  84. bgHeight = Math.min(height*settings.maxZoom, bgHeight);
  85. }
  86. // Take the percent offset and apply it to the new size:
  87. bgPosX = offsetX - (bgWidth * bgRatioX);
  88. bgPosY = offsetY - (bgHeight * bgRatioY);
  89. if (bgWidth < 1000)
  90. {
  91. bgPosX = 0.0;
  92. bgPosY = 0.0;
  93. }
  94. // Prevent zooming out beyond the starting size
  95. if (bgWidth <= width || bgHeight <= height) {
  96. //reset();
  97. updateBgStyle();
  98. } else {
  99. updateBgStyle();
  100. }
  101. }
  102. function drag(e) {
  103. e.preventDefault();
  104. bgPosX += (e.pageX - previousEvent.pageX);
  105. bgPosY += (e.pageY - previousEvent.pageY);
  106. previousEvent = e;
  107. updateBgStyle();
  108. }
  109. function removeDrag() {
  110. document.removeEventListener('mouseup', removeDrag);
  111. document.removeEventListener('mousemove', drag);
  112. }
  113. // Make the background draggable
  114. function draggable(e) {
  115. e.preventDefault();
  116. previousEvent = e;
  117. document.addEventListener('mousemove', drag);
  118. document.addEventListener('mouseup', removeDrag);
  119. }
  120. function load() {
  121. var initial = Math.max(settings.initialZoom, 1);
  122. if (img.src === transparentSpaceFiller) return;
  123. var computedStyle = window.getComputedStyle(img, null);
  124. width = parseInt(computedStyle.width, 10);
  125. height = parseInt(computedStyle.height, 10);
  126. bgWidth = width * initial;
  127. bgHeight = height * initial;
  128. bgPosX = -(bgWidth - width) * settings.initialX;
  129. bgPosY = -(bgHeight - height) * settings.initialY;
  130. setSrcToBackground(img);
  131. img.style.backgroundSize = bgWidth+'px '+bgHeight+'px';
  132. img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px';
  133. img.addEventListener('wheelzoom.reset', reset);
  134. img.addEventListener('wheel', onwheel);
  135. img.addEventListener('mousedown', draggable);
  136. }
  137. var destroy = function (originalProperties) {
  138. img.removeEventListener('wheelzoom.destroy', destroy);
  139. img.removeEventListener('wheelzoom.reset', reset);
  140. img.removeEventListener('load', load);
  141. img.removeEventListener('mouseup', removeDrag);
  142. img.removeEventListener('mousemove', drag);
  143. img.removeEventListener('mousedown', draggable);
  144. img.removeEventListener('wheel', onwheel);
  145. img.style.backgroundImage = originalProperties.backgroundImage;
  146. img.style.backgroundRepeat = originalProperties.backgroundRepeat;
  147. img.src = originalProperties.src;
  148. }.bind(null, {
  149. backgroundImage: img.style.backgroundImage,
  150. backgroundRepeat: img.style.backgroundRepeat,
  151. src: img.src
  152. });
  153. img.addEventListener('wheelzoom.destroy', destroy);
  154. options = options || {};
  155. Object.keys(defaults).forEach(function(key){
  156. settings[key] = options[key] !== undefined ? options[key] : defaults[key];
  157. });
  158. if (img.complete) {
  159. load();
  160. }
  161. img.addEventListener('load', load);
  162. };
  163. // Do nothing in IE9 or below
  164. if (typeof window.btoa !== 'function') {
  165. return function(elements) {
  166. return elements;
  167. };
  168. } else {
  169. return function(elements, options) {
  170. if (elements && elements.length) {
  171. Array.prototype.forEach.call(elements, function (node) {
  172. main(node, options);
  173. });
  174. } else if (elements && elements.nodeName) {
  175. main(elements, options);
  176. }
  177. return elements;
  178. };
  179. }
  180. }());