You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

787 lines
28 KiB

  1. /*
  2. ImageViewer v 1.1.3
  3. Author: Sudhanshu Yadav
  4. Copyright (c) 2015-2016 to Sudhanshu Yadav - ignitersworld.com , released under the MIT license.
  5. Demo on: http://ignitersworld.com/lab/imageViewer.html
  6. */
  7. /*** picture view plugin ****/
  8. (function ($, window, document, undefined) {
  9. "use strict";
  10. //an empty function
  11. var noop = function () {};
  12. var $body = $('body'),
  13. $window = $(window),
  14. $document = $(document);
  15. //constants
  16. var ZOOM_CONSTANT = 15; //increase or decrease value for zoom on mouse wheel
  17. var MOUSE_WHEEL_COUNT = 5; //A mouse delta after which it should stop preventing default behaviour of mouse wheel
  18. //ease out method
  19. /*
  20. t : current time,
  21. b : intial value,
  22. c : changed value,
  23. d : duration
  24. */
  25. function easeOutQuart(t, b, c, d) {
  26. t /= d;
  27. t--;
  28. return -c * (t * t * t * t - 1) + b;
  29. };
  30. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  31. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  32. // requestAnimationFrame polyfill by Erik Möller
  33. // fixes from Paul Irish and Tino Zijdel
  34. (function () {
  35. var lastTime = 0;
  36. var vendors = ['ms', 'moz', 'webkit', 'o'];
  37. for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  38. window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
  39. window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
  40. }
  41. if (!window.requestAnimationFrame)
  42. window.requestAnimationFrame = function (callback, element) {
  43. var currTime = new Date().getTime();
  44. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  45. var id = window.setTimeout(function () {
  46. callback(currTime + timeToCall);
  47. },
  48. timeToCall);
  49. lastTime = currTime + timeToCall;
  50. return id;
  51. };
  52. if (!window.cancelAnimationFrame)
  53. window.cancelAnimationFrame = function (id) {
  54. clearTimeout(id);
  55. };
  56. }());
  57. //function to check if image is loaded
  58. function imageLoaded(img) {
  59. return img.complete && (typeof img.naturalWidth === 'undefined' || img.naturalWidth !== 0);
  60. }
  61. var imageViewHtml = '<div class="iv-loader"></div> <div class="iv-snap-view">' + '<div class="iv-snap-image-wrap">' + '<div class="iv-snap-handle"></div>' + '</div>' + '<div class="iv-zoom-slider"><div class="iv-zoom-handle"></div></div></div>' + '<div class="iv-image-view" ><div class="iv-image-wrap" ></div></div>';
  62. //add a full screen view
  63. $(function () {
  64. if(!$body.length) $body = $('body');
  65. $body.append('<div id="iv-container">' + imageViewHtml + '<div class="iv-close"></div><div>');
  66. });
  67. function Slider(container, options) {
  68. this.container = container;
  69. this.onStart = options.onStart || noop;
  70. this.onMove = options.onMove || noop;
  71. this.onEnd = options.onEnd || noop;
  72. this.sliderId = options.sliderId || 'slider' + Math.ceil(Math.random() * 1000000);
  73. }
  74. Slider.prototype.init = function () {
  75. var self = this,
  76. container = this.container,
  77. eventSuffix = '.' + this.sliderId;
  78. //assign event on snap image wrap
  79. this.container.on('touchstart' + eventSuffix + ' mousedown' + eventSuffix, function (estart) {
  80. estart.preventDefault();
  81. var touchMove = (estart.type == "touchstart" ? "touchmove" : "mousemove") + eventSuffix,
  82. touchEnd = (estart.type == "touchstart" ? "touchend" : "mouseup") + eventSuffix,
  83. eOrginal = estart.originalEvent,
  84. sx = eOrginal.clientX || eOrginal.touches[0].clientX,
  85. sy = eOrginal.clientY || eOrginal.touches[0].clientY;
  86. var start = self.onStart(estart, {
  87. x: sx,
  88. y: sy
  89. });
  90. if (start === false) return;
  91. var moveListener = function (emove) {
  92. emove.preventDefault();
  93. eOrginal = emove.originalEvent;
  94. //get the cordinates
  95. var mx = eOrginal.clientX || eOrginal.touches[0].clientX,
  96. my = eOrginal.clientY || eOrginal.touches[0].clientY;
  97. self.onMove(emove, {
  98. dx: mx - sx,
  99. dy: my - sy,
  100. mx: mx,
  101. my: my
  102. });
  103. };
  104. var endListener = function () {
  105. $document.off(touchMove, moveListener);
  106. $document.off(touchEnd, endListener);
  107. self.onEnd();
  108. };
  109. $document.on(touchMove, moveListener);
  110. $document.on(touchEnd, endListener);
  111. });
  112. return this;
  113. }
  114. function ImageViewer(container, options) {
  115. var self = this;
  116. if (container.is('#iv-container')) {
  117. self._fullPage = true;
  118. }
  119. self.container = container;
  120. options = self.options = $.extend({}, ImageViewer.defaults, options);
  121. self.zoomValue = 100;
  122. if (!container.find('.snap-view').length) {
  123. container.prepend(imageViewHtml);
  124. }
  125. container.addClass('iv-container');
  126. if (container.css('position') == 'static') container.css('position', 'relative');
  127. self.snapView = container.find('.iv-snap-view');
  128. self.snapImageWrap = container.find('.iv-snap-image-wrap');
  129. self.imageWrap = container.find('.iv-image-wrap');
  130. self.snapHandle = container.find('.iv-snap-handle');
  131. self.zoomHandle = container.find('.iv-zoom-handle');
  132. self._viewerId = 'iv' + Math.floor(Math.random() * 1000000);
  133. }
  134. ImageViewer.prototype = {
  135. constructor: ImageViewer,
  136. _init: function () {
  137. var viewer = this,
  138. options = viewer.options,
  139. zooming = false, // tell weather we are zooming trough touch
  140. container = this.container;
  141. var eventSuffix = '.' + viewer._viewerId;
  142. //cache dom refrence
  143. var snapHandle = this.snapHandle;
  144. var snapImgWrap = this.snapImageWrap;
  145. var imageWrap = this.imageWrap;
  146. var snapSlider = new Slider(snapImgWrap, {
  147. sliderId: viewer._viewerId,
  148. onStart: function () {
  149. if (!viewer.loaded) return false;
  150. var handleStyle = snapHandle[0].style;
  151. this.curHandleTop = parseFloat(handleStyle.top);
  152. this.curHandleLeft = parseFloat(handleStyle.left);
  153. this.handleWidth = parseFloat(handleStyle.width);
  154. this.handleHeight = parseFloat(handleStyle.height);
  155. this.width = snapImgWrap.width();
  156. this.height = snapImgWrap.height();
  157. //stop momentum on image
  158. clearInterval(imageSlider.slideMomentumCheck);
  159. cancelAnimationFrame(imageSlider.sliderMomentumFrame);
  160. },
  161. onMove: function (e, position) {
  162. var xPerc = this.curHandleLeft + position.dx * 100 / this.width,
  163. yPerc = this.curHandleTop + position.dy * 100 / this.height;
  164. xPerc = Math.max(0, xPerc);
  165. xPerc = Math.min(100 - this.handleWidth, xPerc);
  166. yPerc = Math.max(0, yPerc);
  167. yPerc = Math.min(100 - this.handleHeight, yPerc);
  168. var containerDim = viewer.containerDim,
  169. imgWidth = viewer.imageDim.w * (viewer.zoomValue / 100),
  170. imgHeight = viewer.imageDim.h * (viewer.zoomValue / 100),
  171. imgLeft = imgWidth < containerDim.w ? (containerDim.w - imgWidth) / 2 : -imgWidth * xPerc / 100,
  172. imgTop = imgHeight < containerDim.h ? (containerDim.h - imgHeight) / 2 : -imgHeight * yPerc / 100;
  173. snapHandle.css({
  174. top: yPerc + '%',
  175. left: xPerc + '%'
  176. })
  177. viewer.currentImg.css({
  178. left: imgLeft,
  179. top: imgTop
  180. })
  181. }
  182. }).init();
  183. /*Add slide interaction to image*/
  184. var imageSlider = viewer._imageSlider = new Slider(imageWrap, {
  185. sliderId: viewer._viewerId,
  186. onStart: function (e, position) {
  187. if (!viewer.loaded) return false;
  188. if (zooming) return;
  189. var self = this;
  190. snapSlider.onStart();
  191. self.imgWidth = viewer.imageDim.w * viewer.zoomValue / 100;
  192. self.imgHeight = viewer.imageDim.h * viewer.zoomValue / 100;
  193. self.positions = [position, position];
  194. self.startPosition = position;
  195. //clear all animation frame and interval
  196. viewer._clearFrames();
  197. self.slideMomentumCheck = setInterval(function () {
  198. if (!self.currentPos) return;
  199. self.positions.shift();
  200. self.positions.push({
  201. x: self.currentPos.mx,
  202. y: self.currentPos.my
  203. })
  204. }, 50);
  205. },
  206. onMove: function (e, position) {
  207. if (zooming) return;
  208. this.currentPos = position;
  209. snapSlider.onMove(e, {
  210. dx: -position.dx * snapSlider.width / this.imgWidth,
  211. dy: -position.dy * snapSlider.height / this.imgHeight
  212. });
  213. },
  214. onEnd: function () {
  215. if (zooming) return;
  216. var self = this;
  217. var xDiff = this.positions[1].x - this.positions[0].x,
  218. yDiff = this.positions[1].y - this.positions[0].y;
  219. function momentum() {
  220. if (step <= 60) {
  221. self.sliderMomentumFrame = requestAnimationFrame(momentum);
  222. }
  223. positionX = positionX + easeOutQuart(step, xDiff / 3, -xDiff / 3, 60);
  224. positionY = positionY + easeOutQuart(step, yDiff / 3, -yDiff / 3, 60)
  225. snapSlider.onMove(null, {
  226. dx: -((positionX) * snapSlider.width / self.imgWidth),
  227. dy: -((positionY) * snapSlider.height / self.imgHeight)
  228. });
  229. step++;
  230. }
  231. if (Math.abs(xDiff) > 30 || Math.abs(yDiff) > 30) {
  232. var step = 1,
  233. positionX = self.currentPos.dx,
  234. positionY = self.currentPos.dy;
  235. momentum();
  236. }
  237. }
  238. }).init();
  239. /*Add zoom interation in mouse wheel*/
  240. var changedDelta = 0;
  241. imageWrap.on("mousewheel" + eventSuffix + " DOMMouseScroll" + eventSuffix, function (e) {
  242. if(!options.zoomOnMouseWheel) return;
  243. if (!viewer.loaded) return;
  244. //clear all animation frame and interval
  245. viewer._clearFrames();
  246. // cross-browser wheel delta
  247. var delta = Math.max(-1, Math.min(1, (e.originalEvent.wheelDelta || -e.originalEvent.detail))),
  248. zoomValue = viewer.zoomValue * (100 + delta * ZOOM_CONSTANT) / 100;
  249. if(!(zoomValue >= 100 && zoomValue <= options.maxZoom)){
  250. changedDelta += Math.abs(delta);
  251. }
  252. else{
  253. changedDelta = 0;
  254. }
  255. if(changedDelta > MOUSE_WHEEL_COUNT) return;
  256. e.preventDefault();
  257. var contOffset = container.offset(),
  258. x = (e.pageX || e.originalEvent.pageX) - contOffset.left,
  259. y = (e.pageY || e.originalEvent.pageY) - contOffset.top;
  260. viewer.zoom(zoomValue, {
  261. x: x,
  262. y: y
  263. });
  264. //show the snap viewer
  265. showSnapView();
  266. });
  267. //apply pinch and zoom feature
  268. imageWrap.on('touchstart' + eventSuffix, function (estart) {
  269. if (!viewer.loaded) return;
  270. var touch0 = estart.originalEvent.touches[0],
  271. touch1 = estart.originalEvent.touches[1];
  272. if (!(touch0 && touch1)) {
  273. return;
  274. }
  275. zooming = true;
  276. var contOffset = container.offset();
  277. var startdist = Math.sqrt(Math.pow(touch1.pageX - touch0.pageX, 2) + Math.pow(touch1.pageY - touch0.pageY, 2)),
  278. startZoom = viewer.zoomValue,
  279. center = {
  280. x: ((touch1.pageX + touch0.pageX) / 2) - contOffset.left,
  281. y: ((touch1.pageY + touch0.pageY) / 2) - contOffset.top
  282. }
  283. var moveListener = function (emove) {
  284. emove.preventDefault();
  285. var touch0 = emove.originalEvent.touches[0],
  286. touch1 = emove.originalEvent.touches[1],
  287. newDist = Math.sqrt(Math.pow(touch1.pageX - touch0.pageX, 2) + Math.pow(touch1.pageY - touch0.pageY, 2)),
  288. zoomValue = startZoom + (newDist - startdist) / 2;
  289. viewer.zoom(zoomValue, center);
  290. };
  291. var endListener = function () {
  292. $document.off('touchmove', moveListener);
  293. $document.off('touchend', endListener);
  294. zooming = false;
  295. };
  296. $document.on('touchmove', moveListener);
  297. $document.on('touchend', endListener);
  298. });
  299. //handle double tap for zoom in and zoom out
  300. var touchtime = 0,
  301. point;
  302. imageWrap.on('click' + eventSuffix, function (e) {
  303. if (touchtime == 0) {
  304. touchtime = Date.now();
  305. point = {
  306. x: e.pageX,
  307. y: e.pageY
  308. };
  309. } else {
  310. if ((Date.now() - touchtime) < 500 && Math.abs(e.pageX - point.x) < 50 && Math.abs(e.pageY - point.y) < 50) {
  311. if (viewer.zoomValue == options.zoomValue) {
  312. viewer.zoom(200)
  313. } else {
  314. viewer.resetZoom()
  315. }
  316. touchtime = 0;
  317. } else {
  318. touchtime = 0;
  319. }
  320. }
  321. });
  322. //zoom in zoom out using zoom handle
  323. var slider = viewer.snapView.find('.iv-zoom-slider');
  324. var zoomSlider = new Slider(slider, {
  325. sliderId: viewer._viewerId,
  326. onStart: function (eStart) {
  327. if (!viewer.loaded) return false;
  328. this.leftOffset = slider.offset().left;
  329. this.handleWidth = viewer.zoomHandle.width();
  330. this.onMove(eStart);
  331. },
  332. onMove: function (e, position) {
  333. var newLeft = (e.pageX || e.originalEvent.touches[0].pageX) - this.leftOffset - this.handleWidth / 2;
  334. newLeft = Math.max(0, newLeft);
  335. newLeft = Math.min(viewer._zoomSliderLength, newLeft);
  336. var zoomValue = 100 + (options.maxZoom - 100) * newLeft / viewer._zoomSliderLength;
  337. viewer.zoom(zoomValue);
  338. }
  339. }).init();
  340. //display snapView on interaction
  341. var snapViewTimeout, snapViewVisible;
  342. function showSnapView(noTimeout) {
  343. if(!options.snapView) return;
  344. if (snapViewVisible || viewer.zoomValue <= 100 || !viewer.loaded) return;
  345. clearTimeout(snapViewTimeout);
  346. snapViewVisible = true;
  347. viewer.snapView.css('opacity', 1);
  348. if (!noTimeout) {
  349. snapViewTimeout = setTimeout(function () {
  350. viewer.snapView.css('opacity', 0);
  351. snapViewVisible = false;
  352. }, 4000);
  353. }
  354. }
  355. imageWrap.on('touchmove' + eventSuffix + ' mousemove' + eventSuffix, function () {
  356. showSnapView();
  357. });
  358. var snapEventsCallback = {};
  359. snapEventsCallback['mouseenter' + eventSuffix + ' touchstart' + eventSuffix] = function () {
  360. snapViewVisible = false;
  361. showSnapView(true);
  362. };
  363. snapEventsCallback['mouseleave' + eventSuffix + ' touchend' + eventSuffix] = function () {
  364. snapViewVisible = false;
  365. showSnapView();
  366. };
  367. viewer.snapView.on(snapEventsCallback);
  368. //calculate elments size on window resize
  369. if (options.refreshOnResize) $window.on('resize' + eventSuffix, function () {
  370. viewer.refresh()
  371. });
  372. if (viewer._fullPage) {
  373. //prevent scrolling the backside if container if fixed positioned
  374. container.on('touchmove' + eventSuffix + ' mousewheel' + eventSuffix + ' DOMMouseScroll' + eventSuffix, function (e) {
  375. e.preventDefault();
  376. });
  377. //assign event on close button
  378. container.find('.iv-close').on('click' + eventSuffix, function () {
  379. viewer.hide();
  380. });
  381. }
  382. },
  383. //method to zoom images
  384. zoom: function (perc, point) {
  385. perc = Math.round(Math.max(100, perc));
  386. perc = Math.min(this.options.maxZoom, perc);
  387. point = point || {
  388. x: this.containerDim.w / 2,
  389. y: this.containerDim.h / 2
  390. };
  391. var self = this,
  392. maxZoom = this.options.maxZoom,
  393. curPerc = this.zoomValue,
  394. curImg = this.currentImg,
  395. containerDim = this.containerDim,
  396. curLeft = parseFloat(curImg.css('left')),
  397. curTop = parseFloat(curImg.css('top'));
  398. self._clearFrames();
  399. var step = 0;
  400. //calculate base top,left,bottom,right
  401. var containerDim = self.containerDim,
  402. imageDim = self.imageDim;
  403. var baseLeft = (containerDim.w - imageDim.w) / 2,
  404. baseTop = (containerDim.h - imageDim.h) / 2,
  405. baseRight = containerDim.w - baseLeft,
  406. baseBottom = containerDim.h - baseTop;
  407. function zoom() {
  408. step++;
  409. if (step < 20) {
  410. self._zoomFrame = requestAnimationFrame(zoom);
  411. }
  412. var tickZoom = easeOutQuart(step, curPerc, perc - curPerc, 20);
  413. var ratio = tickZoom / curPerc,
  414. imgWidth = self.imageDim.w * tickZoom / 100,
  415. imgHeight = self.imageDim.h * tickZoom / 100,
  416. newLeft = -((point.x - curLeft) * ratio - point.x),
  417. newTop = -((point.y - curTop) * ratio - point.y);
  418. //fix for left and top
  419. newLeft = Math.min(newLeft, baseLeft);
  420. newTop = Math.min(newTop, baseTop);
  421. //fix for right and bottom
  422. if((newLeft + imgWidth) < baseRight){
  423. newLeft = baseRight - imgWidth; //newLeft - (newLeft + imgWidth - baseRight)
  424. }
  425. if((newTop + imgHeight) < baseBottom){
  426. newTop = baseBottom - imgHeight; //newTop + (newTop + imgHeight - baseBottom)
  427. }
  428. curImg.css({
  429. height: imgHeight + 'px',
  430. width: imgWidth + 'px',
  431. left: newLeft + 'px',
  432. top: newTop + 'px'
  433. });
  434. self.zoomValue = tickZoom;
  435. self._resizeHandle(imgWidth, imgHeight, newLeft, newTop);
  436. //update zoom handle position
  437. self.zoomHandle.css('left', ((tickZoom - 100) * self._zoomSliderLength) / (maxZoom - 100) + 'px');
  438. }
  439. zoom();
  440. },
  441. _clearFrames: function () {
  442. clearInterval(this._imageSlider.slideMomentumCheck);
  443. cancelAnimationFrame(this._imageSlider.sliderMomentumFrame);
  444. cancelAnimationFrame(this._zoomFrame)
  445. },
  446. resetZoom: function () {
  447. this.zoom(this.options.zoomValue);
  448. },
  449. //calculate dimensions of image, container and reset the image
  450. _calculateDimensions: function () {
  451. //calculate content width of image and snap image
  452. var self = this,
  453. curImg = self.currentImg,
  454. container = self.container,
  455. snapView = self.snapView,
  456. imageWidth = curImg.width(),
  457. imageHeight = curImg.height(),
  458. contWidth = container.width(),
  459. contHeight = container.height(),
  460. snapViewWidth = snapView.innerWidth(),
  461. snapViewHeight = snapView.innerHeight();
  462. //set the container dimension
  463. self.containerDim = {
  464. w: contWidth,
  465. h: contHeight
  466. }
  467. //set the image dimension
  468. var imgWidth, imgHeight, ratio = imageWidth / imageHeight;
  469. imgWidth = (imageWidth > imageHeight && contHeight >= contWidth) || ratio * contHeight > contWidth ? contWidth : ratio * contHeight;
  470. imgHeight = imgWidth / ratio;
  471. self.imageDim = {
  472. w: imgWidth,
  473. h: imgHeight
  474. }
  475. //reset image position and zoom
  476. curImg.css({
  477. width: imgWidth + 'px',
  478. height: imgHeight + 'px',
  479. left: (contWidth - imgWidth) / 2 + 'px',
  480. top: (contHeight - imgHeight) / 2 + 'px',
  481. 'max-width': 'none',
  482. 'max-height': 'none'
  483. });
  484. //set the snap Image dimension
  485. var snapWidth = imgWidth > imgHeight ? snapViewWidth : imgWidth * snapViewHeight / imgHeight,
  486. snapHeight = imgHeight > imgWidth ? snapViewHeight : imgHeight * snapViewWidth / imgWidth;
  487. self.snapImageDim = {
  488. w: snapWidth,
  489. h: snapHeight
  490. }
  491. self.snapImg.css({
  492. width: snapWidth,
  493. height: snapHeight
  494. });
  495. //calculate zoom slider area
  496. self._zoomSliderLength = snapViewWidth - self.zoomHandle.outerWidth();
  497. },
  498. refresh: function () {
  499. if (!this.loaded) return;
  500. this._calculateDimensions();
  501. this.resetZoom();
  502. },
  503. _resizeHandle: function (imgWidth, imgHeight, imgLeft, imgTop) {
  504. var curImg = this.currentImg,
  505. imageWidth = imgWidth || this.imageDim.w * this.zoomValue / 100,
  506. imageHeight = imgHeight || this.imageDim.h * this.zoomValue / 100,
  507. left = Math.max(-(imgLeft || parseFloat(curImg.css('left'))) * 100 / imageWidth, 0),
  508. top = Math.max(-(imgTop || parseFloat(curImg.css('top'))) * 100 / imageHeight, 0),
  509. handleWidth = Math.min(this.containerDim.w * 100 / imageWidth, 100),
  510. handleHeight = Math.min(this.containerDim.h * 100 / imageHeight, 100);
  511. this.snapHandle.css({
  512. top: top + '%',
  513. left: left + '%',
  514. width: handleWidth + '%',
  515. height: handleHeight + '%'
  516. });
  517. },
  518. show: function (image, hiResImg) {
  519. if (this._fullPage) {
  520. this.container.show();
  521. if (image) this.load(image, hiResImg);
  522. }
  523. },
  524. hide: function () {
  525. if (this._fullPage) {
  526. this.container.hide();
  527. }
  528. },
  529. options: function (key, value) {
  530. if (!value) return this.options[key];
  531. this.options[key] = value;
  532. },
  533. destroy: function (key, value) {
  534. var eventSuffix = '.' + this._viewerId;
  535. if (this._fullPage) {
  536. container.off(eventSuffix);
  537. container.find('[class^="iv"]').off(eventSuffix);
  538. } else {
  539. this.container.remove('[class^="iv"]');
  540. }
  541. $window.off(eventSuffix);
  542. return null;
  543. },
  544. load: function (image, hiResImg) {
  545. var self = this,
  546. container = this.container;
  547. container.find('.iv-snap-image,.iv-large-image').remove();
  548. var snapImageWrap = this.container.find('.iv-snap-image-wrap');
  549. snapImageWrap.prepend('<img class="iv-snap-image" src="' + image + '" />');
  550. this.imageWrap.prepend('<img class="iv-large-image" src="' + image + '" />');
  551. if (hiResImg) {
  552. this.imageWrap.append('<img class="iv-large-image" src="' + hiResImg + '" />')
  553. }
  554. var currentImg = this.currentImg = this.container.find('.iv-large-image');
  555. this.snapImg = this.container.find('.iv-snap-image');
  556. self.loaded = false;
  557. //show loader
  558. container.find('.iv-loader').show();
  559. currentImg.hide();
  560. self.snapImg.hide();
  561. //refresh the view
  562. function refreshView() {
  563. self.loaded = true;
  564. self.zoomValue = 100;
  565. //reset zoom of images
  566. currentImg.show();
  567. self.snapImg.show();
  568. self.refresh();
  569. self.resetZoom();
  570. //hide loader
  571. container.find('.iv-loader').hide();
  572. }
  573. if (imageLoaded(currentImg[0])) {
  574. refreshView();
  575. } else {
  576. $(currentImg[0]).on('load', refreshView);
  577. }
  578. }
  579. }
  580. ImageViewer.defaults = {
  581. zoomValue: 100,
  582. snapView: true,
  583. maxZoom: 500,
  584. refreshOnResize: true,
  585. zoomOnMouseWheel : true
  586. }
  587. window.ImageViewer = function (container, options) {
  588. var imgElm, imgSrc, hiResImg;
  589. if (!(container && (typeof container == "string" || container instanceof Element || container[0] instanceof Element))) {
  590. options = container;
  591. container = $('#iv-container');
  592. }
  593. container = $(container);
  594. if (container.is('img')) {
  595. imgElm = container;
  596. imgSrc = imgElm[0].src;
  597. hiResImg = imgElm.attr('high-res-src') || imgElm.attr('data-high-res-src');
  598. container = imgElm.wrap('<div class="iv-container" style="display:inline-block; overflow:hidden"></div>').parent();
  599. imgElm.css({
  600. opacity: 0,
  601. position: 'relative',
  602. zIndex: -1
  603. });
  604. } else {
  605. imgSrc = container.attr('src') || container.attr('data-src');
  606. hiResImg = container.attr('high-res-src') || container.attr('data-high-res-src');
  607. }
  608. var viewer = new ImageViewer(container, options);
  609. viewer._init();
  610. if (imgSrc) viewer.load(imgSrc, hiResImg);
  611. return viewer;
  612. };
  613. $.fn.ImageViewer = function (options) {
  614. return this.each(function () {
  615. var $this = $(this);
  616. var viewer = window.ImageViewer($this, options);
  617. $this.data('ImageViewer', viewer);
  618. });
  619. }
  620. }((window.jQuery), window, document));