lg-zoom.es5.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. /*!
  2. * lightgallery | 2.4.0-beta.0 | December 12th 2021
  3. * http://www.lightgalleryjs.com/
  4. * Copyright (c) 2020 Sachin Neravath;
  5. * @license GPLv3
  6. */
  7. /*! *****************************************************************************
  8. Copyright (c) Microsoft Corporation.
  9. Permission to use, copy, modify, and/or distribute this software for any
  10. purpose with or without fee is hereby granted.
  11. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  12. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  13. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  14. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  16. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. PERFORMANCE OF THIS SOFTWARE.
  18. ***************************************************************************** */
  19. var __assign = function() {
  20. __assign = Object.assign || function __assign(t) {
  21. for (var s, i = 1, n = arguments.length; i < n; i++) {
  22. s = arguments[i];
  23. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  24. }
  25. return t;
  26. };
  27. return __assign.apply(this, arguments);
  28. };
  29. var zoomSettings = {
  30. scale: 1,
  31. zoom: true,
  32. actualSize: true,
  33. showZoomInOutIcons: false,
  34. actualSizeIcons: {
  35. zoomIn: 'lg-zoom-in',
  36. zoomOut: 'lg-zoom-out',
  37. },
  38. enableZoomAfter: 300,
  39. zoomPluginStrings: {
  40. zoomIn: 'Zoom in',
  41. zoomOut: 'Zoom out',
  42. viewActualSize: 'View actual size',
  43. },
  44. };
  45. /**
  46. * List of lightGallery events
  47. * All events should be documented here
  48. * Below interfaces are used to build the website documentations
  49. * */
  50. var lGEvents = {
  51. afterAppendSlide: 'lgAfterAppendSlide',
  52. init: 'lgInit',
  53. hasVideo: 'lgHasVideo',
  54. containerResize: 'lgContainerResize',
  55. updateSlides: 'lgUpdateSlides',
  56. afterAppendSubHtml: 'lgAfterAppendSubHtml',
  57. beforeOpen: 'lgBeforeOpen',
  58. afterOpen: 'lgAfterOpen',
  59. slideItemLoad: 'lgSlideItemLoad',
  60. beforeSlide: 'lgBeforeSlide',
  61. afterSlide: 'lgAfterSlide',
  62. posterClick: 'lgPosterClick',
  63. dragStart: 'lgDragStart',
  64. dragMove: 'lgDragMove',
  65. dragEnd: 'lgDragEnd',
  66. beforeNextSlide: 'lgBeforeNextSlide',
  67. beforePrevSlide: 'lgBeforePrevSlide',
  68. beforeClose: 'lgBeforeClose',
  69. afterClose: 'lgAfterClose',
  70. rotateLeft: 'lgRotateLeft',
  71. rotateRight: 'lgRotateRight',
  72. flipHorizontal: 'lgFlipHorizontal',
  73. flipVertical: 'lgFlipVertical',
  74. autoplay: 'lgAutoplay',
  75. autoplayStart: 'lgAutoplayStart',
  76. autoplayStop: 'lgAutoplayStop',
  77. };
  78. var Zoom = /** @class */ (function () {
  79. function Zoom(instance, $LG) {
  80. // get lightGallery core plugin instance
  81. this.core = instance;
  82. this.$LG = $LG;
  83. this.settings = __assign(__assign({}, zoomSettings), this.core.settings);
  84. return this;
  85. }
  86. // Append Zoom controls. Actual size, Zoom-in, Zoom-out
  87. Zoom.prototype.buildTemplates = function () {
  88. var zoomIcons = this.settings.showZoomInOutIcons
  89. ? "<button id=\"" + this.core.getIdName('lg-zoom-in') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-in lg-icon\"></button><button id=\"" + this.core.getIdName('lg-zoom-out') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-out lg-icon\"></button>"
  90. : '';
  91. if (this.settings.actualSize) {
  92. zoomIcons += "<button id=\"" + this.core.getIdName('lg-actual-size') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['viewActualSize'] + "\" class=\"" + this.settings.actualSizeIcons.zoomIn + " lg-icon\"></button>";
  93. }
  94. this.core.outer.addClass('lg-use-transition-for-zoom');
  95. this.core.$toolbar.first().append(zoomIcons);
  96. };
  97. /**
  98. * @desc Enable zoom option only once the image is completely loaded
  99. * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted
  100. *
  101. * Zoom styles are defined under lg-zoomable CSS class.
  102. */
  103. Zoom.prototype.enableZoom = function (event) {
  104. var _this = this;
  105. // delay will be 0 except first time
  106. var _speed = this.settings.enableZoomAfter + event.detail.delay;
  107. // set _speed value 0 if gallery opened from direct url and if it is first slide
  108. if (this.$LG('body').first().hasClass('lg-from-hash') &&
  109. event.detail.delay) {
  110. // will execute only once
  111. _speed = 0;
  112. }
  113. else {
  114. // Remove lg-from-hash to enable starting animation.
  115. this.$LG('body').first().removeClass('lg-from-hash');
  116. }
  117. this.zoomableTimeout = setTimeout(function () {
  118. if (!_this.isImageSlide()) {
  119. return;
  120. }
  121. _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable');
  122. if (event.detail.index === _this.core.index) {
  123. _this.setZoomEssentials();
  124. }
  125. }, _speed + 30);
  126. };
  127. Zoom.prototype.enableZoomOnSlideItemLoad = function () {
  128. // Add zoomable class
  129. this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this));
  130. };
  131. Zoom.prototype.getModifier = function (rotateValue, axis, el) {
  132. var originalRotate = rotateValue;
  133. rotateValue = Math.abs(rotateValue);
  134. var transformValues = this.getCurrentTransform(el);
  135. if (!transformValues) {
  136. return 1;
  137. }
  138. var modifier = 1;
  139. if (axis === 'X') {
  140. var flipHorizontalValue = Math.sign(parseFloat(transformValues[0]));
  141. if (rotateValue === 0 || rotateValue === 180) {
  142. modifier = 1;
  143. }
  144. else if (rotateValue === 90) {
  145. if ((originalRotate === -90 && flipHorizontalValue === 1) ||
  146. (originalRotate === 90 && flipHorizontalValue === -1)) {
  147. modifier = -1;
  148. }
  149. else {
  150. modifier = 1;
  151. }
  152. }
  153. modifier = modifier * flipHorizontalValue;
  154. }
  155. else {
  156. var flipVerticalValue = Math.sign(parseFloat(transformValues[3]));
  157. if (rotateValue === 0 || rotateValue === 180) {
  158. modifier = 1;
  159. }
  160. else if (rotateValue === 90) {
  161. var sinX = parseFloat(transformValues[1]);
  162. var sinMinusX = parseFloat(transformValues[2]);
  163. modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue);
  164. }
  165. modifier = modifier * flipVerticalValue;
  166. }
  167. return modifier;
  168. };
  169. Zoom.prototype.getImageSize = function ($image, rotateValue, axis) {
  170. var imageSizes = {
  171. y: 'offsetHeight',
  172. x: 'offsetWidth',
  173. };
  174. if (Math.abs(rotateValue) === 90) {
  175. // Swap axis
  176. if (axis === 'x') {
  177. axis = 'y';
  178. }
  179. else {
  180. axis = 'x';
  181. }
  182. }
  183. return $image[imageSizes[axis]];
  184. };
  185. Zoom.prototype.getDragCords = function (e, rotateValue) {
  186. if (rotateValue === 90) {
  187. return {
  188. x: e.pageY,
  189. y: e.pageX,
  190. };
  191. }
  192. else {
  193. return {
  194. x: e.pageX,
  195. y: e.pageY,
  196. };
  197. }
  198. };
  199. Zoom.prototype.getSwipeCords = function (e, rotateValue) {
  200. var x = e.targetTouches[0].pageX;
  201. var y = e.targetTouches[0].pageY;
  202. if (rotateValue === 90) {
  203. return {
  204. x: y,
  205. y: x,
  206. };
  207. }
  208. else {
  209. return {
  210. x: x,
  211. y: y,
  212. };
  213. }
  214. };
  215. Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) {
  216. scale = scale || this.scale || 1;
  217. var allowY = this.imageYSize * scale > this.containerRect.height;
  218. var allowX = this.imageXSize * scale > this.containerRect.width;
  219. if (rotateValue === 90) {
  220. return {
  221. allowX: allowY,
  222. allowY: allowX,
  223. };
  224. }
  225. else {
  226. return {
  227. allowX: allowX,
  228. allowY: allowY,
  229. };
  230. }
  231. };
  232. /**
  233. *
  234. * @param {Element} el
  235. * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);
  236. * Get the current transform value
  237. */
  238. Zoom.prototype.getCurrentTransform = function (el) {
  239. if (!el) {
  240. return;
  241. }
  242. var st = window.getComputedStyle(el, null);
  243. var tm = st.getPropertyValue('-webkit-transform') ||
  244. st.getPropertyValue('-moz-transform') ||
  245. st.getPropertyValue('-ms-transform') ||
  246. st.getPropertyValue('-o-transform') ||
  247. st.getPropertyValue('transform') ||
  248. 'none';
  249. if (tm !== 'none') {
  250. return tm.split('(')[1].split(')')[0].split(',');
  251. }
  252. return;
  253. };
  254. Zoom.prototype.getCurrentRotation = function (el) {
  255. if (!el) {
  256. return 0;
  257. }
  258. var values = this.getCurrentTransform(el);
  259. if (values) {
  260. return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) *
  261. (180 / Math.PI));
  262. // If you want rotate in 360
  263. //return (angle < 0 ? angle + 360 : angle);
  264. }
  265. return 0;
  266. };
  267. Zoom.prototype.setZoomEssentials = function () {
  268. var $image = this.core
  269. .getSlideItem(this.core.index)
  270. .find('.lg-image')
  271. .first();
  272. var rotateEl = this.core
  273. .getSlideItem(this.core.index)
  274. .find('.lg-img-rotate')
  275. .first()
  276. .get();
  277. this.rotateValue = this.getCurrentRotation(rotateEl);
  278. this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y');
  279. this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x');
  280. this.containerRect = this.core.outer.get().getBoundingClientRect();
  281. this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl);
  282. this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl);
  283. };
  284. /**
  285. * @desc Image zoom
  286. * Translate the wrap and scale the image to get better user experience
  287. *
  288. * @param {String} scale - Zoom decrement/increment value
  289. */
  290. Zoom.prototype.zoomImage = function (scale) {
  291. // Find offset manually to avoid issue after zoom
  292. var offsetX = (this.containerRect.width - this.imageXSize) / 2 +
  293. this.containerRect.left;
  294. var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
  295. var topBottomSpacing = Math.abs(top - bottom) / 2;
  296. var offsetY = (this.containerRect.height -
  297. this.imageYSize -
  298. topBottomSpacing * this.modifierX) /
  299. 2 +
  300. this.scrollTop +
  301. this.containerRect.top;
  302. var originalX;
  303. var originalY;
  304. if (scale === 1) {
  305. this.positionChanged = false;
  306. }
  307. var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale);
  308. var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX;
  309. if (this.positionChanged) {
  310. originalX = this.left / (this.scale - 1);
  311. originalY = this.top / (this.scale - 1);
  312. this.pageX = Math.abs(originalX) + offsetX;
  313. this.pageY = Math.abs(originalY) + offsetY;
  314. this.positionChanged = false;
  315. }
  316. var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale);
  317. var _x = offsetX - this.pageX;
  318. var _y = offsetY - this.pageY;
  319. var x = (scale - 1) * _x;
  320. var y = (scale - 1) * _y;
  321. if (allowX) {
  322. if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) {
  323. x = possibleSwipeCords.minX;
  324. }
  325. else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) {
  326. x = possibleSwipeCords.maxX;
  327. }
  328. }
  329. else {
  330. if (scale > 1) {
  331. if (x < possibleSwipeCords.minX) {
  332. x = possibleSwipeCords.minX;
  333. }
  334. else if (x > possibleSwipeCords.maxX) {
  335. x = possibleSwipeCords.maxX;
  336. }
  337. }
  338. }
  339. if (allowY) {
  340. if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) {
  341. y = possibleSwipeCords.minY;
  342. }
  343. else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) {
  344. y = possibleSwipeCords.maxY;
  345. }
  346. }
  347. else {
  348. // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out
  349. if (scale > 1) {
  350. //If image goes beyond viewport top, use the minim possible translate value
  351. if (y < possibleSwipeCords.minY) {
  352. y = possibleSwipeCords.minY;
  353. }
  354. else if (y > possibleSwipeCords.maxY) {
  355. y = possibleSwipeCords.maxY;
  356. }
  357. }
  358. }
  359. this.setZoomStyles({
  360. x: x,
  361. y: y,
  362. scale: scale,
  363. });
  364. };
  365. /**
  366. * @desc apply scale3d to image and translate to image wrap
  367. * @param {style} X,Y and scale
  368. */
  369. Zoom.prototype.setZoomStyles = function (style) {
  370. var $image = this.core
  371. .getSlideItem(this.core.index)
  372. .find('.lg-image')
  373. .first();
  374. var $dummyImage = this.core.outer
  375. .find('.lg-current .lg-dummy-img')
  376. .first();
  377. var $imageWrap = $image.parent();
  378. this.scale = style.scale;
  379. $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
  380. $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
  381. var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)';
  382. $imageWrap.css('transform', transform);
  383. this.left = style.x;
  384. this.top = style.y;
  385. };
  386. /**
  387. * @param index - Index of the current slide
  388. * @param event - event will be available only if the function is called on clicking/taping the imags
  389. */
  390. Zoom.prototype.setActualSize = function (index, event) {
  391. var _this = this;
  392. // Allow zoom only on image
  393. if (!this.isImageSlide() ||
  394. this.core.outer.hasClass('lg-first-slide-loading')) {
  395. return;
  396. }
  397. var scale = this.getCurrentImageActualSizeScale();
  398. if (this.core.outer.hasClass('lg-zoomed')) {
  399. this.scale = 1;
  400. }
  401. else {
  402. this.scale = this.getScale(scale);
  403. }
  404. this.setPageCords(event);
  405. this.beginZoom(this.scale);
  406. this.zoomImage(this.scale);
  407. setTimeout(function () {
  408. _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
  409. }, 10);
  410. };
  411. Zoom.prototype.getNaturalWidth = function (index) {
  412. var $image = this.core.getSlideItem(index).find('.lg-image').first();
  413. var naturalWidth = this.core.galleryItems[index].width;
  414. return naturalWidth
  415. ? parseFloat(naturalWidth)
  416. : $image.get().naturalWidth;
  417. };
  418. Zoom.prototype.getActualSizeScale = function (naturalWidth, width) {
  419. var _scale;
  420. var scale;
  421. if (naturalWidth > width) {
  422. _scale = naturalWidth / width;
  423. scale = _scale || 2;
  424. }
  425. else {
  426. scale = 1;
  427. }
  428. return scale;
  429. };
  430. Zoom.prototype.getCurrentImageActualSizeScale = function () {
  431. var $image = this.core
  432. .getSlideItem(this.core.index)
  433. .find('.lg-image')
  434. .first();
  435. var width = $image.get().offsetWidth;
  436. var naturalWidth = this.getNaturalWidth(this.core.index) || width;
  437. return this.getActualSizeScale(naturalWidth, width);
  438. };
  439. Zoom.prototype.getPageCords = function (event) {
  440. var cords = {};
  441. if (event) {
  442. cords.x = event.pageX || event.targetTouches[0].pageX;
  443. cords.y = event.pageY || event.targetTouches[0].pageY;
  444. }
  445. else {
  446. var containerRect = this.core.outer.get().getBoundingClientRect();
  447. cords.x = containerRect.width / 2 + containerRect.left;
  448. cords.y =
  449. containerRect.height / 2 + this.scrollTop + containerRect.top;
  450. }
  451. return cords;
  452. };
  453. Zoom.prototype.setPageCords = function (event) {
  454. var pageCords = this.getPageCords(event);
  455. this.pageX = pageCords.x;
  456. this.pageY = pageCords.y;
  457. };
  458. // If true, zoomed - in else zoomed out
  459. Zoom.prototype.beginZoom = function (scale) {
  460. this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
  461. if (scale > 1) {
  462. this.core.outer.addClass('lg-zoomed');
  463. var $actualSize = this.core.getElementById('lg-actual-size');
  464. $actualSize
  465. .removeClass(this.settings.actualSizeIcons.zoomIn)
  466. .addClass(this.settings.actualSizeIcons.zoomOut);
  467. }
  468. else {
  469. this.resetZoom();
  470. }
  471. return scale > 1;
  472. };
  473. Zoom.prototype.getScale = function (scale) {
  474. var actualSizeScale = this.getCurrentImageActualSizeScale();
  475. if (scale < 1) {
  476. scale = 1;
  477. }
  478. else if (scale > actualSizeScale) {
  479. scale = actualSizeScale;
  480. }
  481. return scale;
  482. };
  483. Zoom.prototype.init = function () {
  484. var _this = this;
  485. if (!this.settings.zoom) {
  486. return;
  487. }
  488. this.buildTemplates();
  489. this.enableZoomOnSlideItemLoad();
  490. var tapped = null;
  491. this.core.outer.on('dblclick.lg', function (event) {
  492. if (!_this.$LG(event.target).hasClass('lg-image')) {
  493. return;
  494. }
  495. _this.setActualSize(_this.core.index, event);
  496. });
  497. this.core.outer.on('touchstart.lg', function (event) {
  498. var $target = _this.$LG(event.target);
  499. if (event.targetTouches.length === 1 &&
  500. $target.hasClass('lg-image')) {
  501. if (!tapped) {
  502. tapped = setTimeout(function () {
  503. tapped = null;
  504. }, 300);
  505. }
  506. else {
  507. clearTimeout(tapped);
  508. tapped = null;
  509. event.preventDefault();
  510. _this.setActualSize(_this.core.index, event);
  511. }
  512. }
  513. });
  514. // Update zoom on resize and orientationchange
  515. this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () {
  516. if (!_this.core.lgOpened || !_this.isImageSlide())
  517. return;
  518. _this.setPageCords();
  519. _this.setZoomEssentials();
  520. _this.zoomImage(_this.scale);
  521. });
  522. // Update zoom on resize and orientationchange
  523. this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () {
  524. if (!_this.core.lgOpened)
  525. return;
  526. _this.scrollTop = _this.$LG(window).scrollTop();
  527. });
  528. this.core.getElementById('lg-zoom-out').on('click.lg', function () {
  529. if (_this.core.outer.find('.lg-current .lg-image').get()) {
  530. _this.scale -= _this.settings.scale;
  531. _this.scale = _this.getScale(_this.scale);
  532. _this.beginZoom(_this.scale);
  533. _this.zoomImage(_this.scale);
  534. }
  535. });
  536. this.core.getElementById('lg-zoom-in').on('click.lg', function () {
  537. _this.zoomIn();
  538. });
  539. this.core.getElementById('lg-actual-size').on('click.lg', function () {
  540. _this.setActualSize(_this.core.index);
  541. });
  542. this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () {
  543. _this.core.outer.find('.lg-item').removeClass('lg-zoomable');
  544. });
  545. this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () {
  546. _this.scrollTop = _this.$LG(window).scrollTop();
  547. // Set the initial value center
  548. _this.pageX = _this.core.outer.width() / 2;
  549. _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop;
  550. _this.scale = 1;
  551. });
  552. // Reset zoom on slide change
  553. this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) {
  554. var prevIndex = event.detail.prevIndex;
  555. _this.scale = 1;
  556. _this.positionChanged = false;
  557. _this.resetZoom(prevIndex);
  558. if (_this.isImageSlide()) {
  559. _this.setZoomEssentials();
  560. }
  561. });
  562. // Drag option after zoom
  563. this.zoomDrag();
  564. this.pinchZoom();
  565. this.zoomSwipe();
  566. // Store the zoomable timeout value just to clear it while closing
  567. this.zoomableTimeout = false;
  568. this.positionChanged = false;
  569. };
  570. Zoom.prototype.zoomIn = function (scale) {
  571. // Allow zoom only on image
  572. if (!this.isImageSlide()) {
  573. return;
  574. }
  575. if (scale) {
  576. this.scale = scale;
  577. }
  578. else {
  579. this.scale += this.settings.scale;
  580. }
  581. this.scale = this.getScale(this.scale);
  582. this.beginZoom(this.scale);
  583. this.zoomImage(this.scale);
  584. };
  585. // Reset zoom effect
  586. Zoom.prototype.resetZoom = function (index) {
  587. this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition');
  588. var $actualSize = this.core.getElementById('lg-actual-size');
  589. var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index);
  590. $actualSize
  591. .removeClass(this.settings.actualSizeIcons.zoomOut)
  592. .addClass(this.settings.actualSizeIcons.zoomIn);
  593. $item.find('.lg-img-wrap').first().removeAttr('style');
  594. $item.find('.lg-image').first().removeAttr('style');
  595. this.scale = 1;
  596. this.left = 0;
  597. this.top = 0;
  598. // Reset pagx pagy values to center
  599. this.setPageCords();
  600. };
  601. Zoom.prototype.getTouchDistance = function (e) {
  602. return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) *
  603. (e.targetTouches[0].pageX - e.targetTouches[1].pageX) +
  604. (e.targetTouches[0].pageY - e.targetTouches[1].pageY) *
  605. (e.targetTouches[0].pageY - e.targetTouches[1].pageY));
  606. };
  607. Zoom.prototype.pinchZoom = function () {
  608. var _this = this;
  609. var startDist = 0;
  610. var pinchStarted = false;
  611. var initScale = 1;
  612. var $item = this.core.getSlideItem(this.core.index);
  613. this.core.$inner.on('touchstart.lg', function (e) {
  614. $item = _this.core.getSlideItem(_this.core.index);
  615. if (!_this.isImageSlide()) {
  616. return;
  617. }
  618. if (e.targetTouches.length === 2 &&
  619. !_this.core.outer.hasClass('lg-first-slide-loading') &&
  620. (_this.$LG(e.target).hasClass('lg-item') ||
  621. $item.get().contains(e.target))) {
  622. initScale = _this.scale || 1;
  623. _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
  624. _this.core.touchAction = 'pinch';
  625. startDist = _this.getTouchDistance(e);
  626. }
  627. });
  628. this.core.$inner.on('touchmove.lg', function (e) {
  629. if (e.targetTouches.length === 2 &&
  630. _this.core.touchAction === 'pinch' &&
  631. (_this.$LG(e.target).hasClass('lg-item') ||
  632. $item.get().contains(e.target))) {
  633. e.preventDefault();
  634. var endDist = _this.getTouchDistance(e);
  635. var distance = startDist - endDist;
  636. if (!pinchStarted && Math.abs(distance) > 5) {
  637. pinchStarted = true;
  638. }
  639. if (pinchStarted) {
  640. _this.scale = Math.max(1, initScale + -distance * 0.008);
  641. _this.zoomImage(_this.scale);
  642. }
  643. }
  644. });
  645. this.core.$inner.on('touchend.lg', function (e) {
  646. if (_this.core.touchAction === 'pinch' &&
  647. (_this.$LG(e.target).hasClass('lg-item') ||
  648. $item.get().contains(e.target))) {
  649. pinchStarted = false;
  650. startDist = 0;
  651. if (_this.scale <= 1) {
  652. _this.resetZoom();
  653. }
  654. else {
  655. _this.scale = _this.getScale(_this.scale);
  656. _this.zoomImage(_this.scale);
  657. _this.core.outer.addClass('lg-zoomed');
  658. }
  659. _this.core.touchAction = undefined;
  660. }
  661. });
  662. };
  663. Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) {
  664. var distanceXnew = endCoords.x - startCoords.x;
  665. var distanceYnew = endCoords.y - startCoords.y;
  666. var speedX = Math.abs(distanceXnew) / touchDuration + 1;
  667. var speedY = Math.abs(distanceYnew) / touchDuration + 1;
  668. if (speedX > 2) {
  669. speedX += 1;
  670. }
  671. if (speedY > 2) {
  672. speedY += 1;
  673. }
  674. distanceXnew = distanceXnew * speedX;
  675. distanceYnew = distanceYnew * speedY;
  676. var _LGel = this.core
  677. .getSlideItem(this.core.index)
  678. .find('.lg-img-wrap')
  679. .first();
  680. var distance = {};
  681. distance.x = this.left + distanceXnew * this.modifierX;
  682. distance.y = this.top + distanceYnew * this.modifierY;
  683. var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue);
  684. if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) {
  685. if (allowY) {
  686. if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
  687. distance.y = possibleSwipeCords.minY;
  688. }
  689. else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
  690. distance.y = possibleSwipeCords.maxY;
  691. }
  692. }
  693. if (allowX) {
  694. if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
  695. distance.x = possibleSwipeCords.minX;
  696. }
  697. else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
  698. distance.x = possibleSwipeCords.maxX;
  699. }
  700. }
  701. if (allowY) {
  702. this.top = distance.y;
  703. }
  704. else {
  705. distance.y = this.top;
  706. }
  707. if (allowX) {
  708. this.left = distance.x;
  709. }
  710. else {
  711. distance.x = this.left;
  712. }
  713. this.setZoomSwipeStyles(_LGel, distance);
  714. this.positionChanged = true;
  715. }
  716. };
  717. Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) {
  718. var distance = {};
  719. if (allowY) {
  720. distance.y =
  721. this.top + (endCoords.y - startCoords.y) * this.modifierY;
  722. if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
  723. var diffMinY = possibleSwipeCords.minY - distance.y;
  724. distance.y = possibleSwipeCords.minY - diffMinY / 6;
  725. }
  726. else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
  727. var diffMaxY = distance.y - possibleSwipeCords.maxY;
  728. distance.y = possibleSwipeCords.maxY + diffMaxY / 6;
  729. }
  730. }
  731. else {
  732. distance.y = this.top;
  733. }
  734. if (allowX) {
  735. distance.x =
  736. this.left + (endCoords.x - startCoords.x) * this.modifierX;
  737. if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
  738. var diffMinX = possibleSwipeCords.minX - distance.x;
  739. distance.x = possibleSwipeCords.minX - diffMinX / 6;
  740. }
  741. else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
  742. var difMaxX = distance.x - possibleSwipeCords.maxX;
  743. distance.x = possibleSwipeCords.maxX + difMaxX / 6;
  744. }
  745. }
  746. else {
  747. distance.x = this.left;
  748. }
  749. return distance;
  750. };
  751. Zoom.prototype.isBeyondPossibleLeft = function (x, minX) {
  752. return x >= minX;
  753. };
  754. Zoom.prototype.isBeyondPossibleRight = function (x, maxX) {
  755. return x <= maxX;
  756. };
  757. Zoom.prototype.isBeyondPossibleTop = function (y, minY) {
  758. return y >= minY;
  759. };
  760. Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) {
  761. return y <= maxY;
  762. };
  763. Zoom.prototype.isImageSlide = function () {
  764. var currentItem = this.core.galleryItems[this.core.index];
  765. return this.core.getSlideType(currentItem) === 'image';
  766. };
  767. Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) {
  768. var dataScale = scale || this.scale || 1;
  769. var elDataScale = Math.abs(dataScale);
  770. var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
  771. var topBottomSpacing = Math.abs(top - bottom) / 2;
  772. var minY = (this.imageYSize - this.containerRect.height) / 2 +
  773. topBottomSpacing * this.modifierX;
  774. var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY;
  775. var minX = (this.imageXSize - this.containerRect.width) / 2;
  776. var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX;
  777. var possibleSwipeCords = {
  778. minY: minY,
  779. maxY: maxY,
  780. minX: minX,
  781. maxX: maxX,
  782. };
  783. if (Math.abs(rotateValue) === 90) {
  784. possibleSwipeCords = {
  785. minY: minX,
  786. maxY: maxX,
  787. minX: minY,
  788. maxX: maxY,
  789. };
  790. }
  791. return possibleSwipeCords;
  792. };
  793. Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) {
  794. LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)');
  795. };
  796. Zoom.prototype.zoomSwipe = function () {
  797. var _this = this;
  798. var startCoords = {};
  799. var endCoords = {};
  800. var isMoved = false;
  801. // Allow x direction drag
  802. var allowX = false;
  803. // Allow Y direction drag
  804. var allowY = false;
  805. var startTime = new Date();
  806. var endTime = new Date();
  807. var possibleSwipeCords;
  808. var _LGel;
  809. var $item = this.core.getSlideItem(this.core.index);
  810. this.core.$inner.on('touchstart.lg', function (e) {
  811. // Allow zoom only on image
  812. if (!_this.isImageSlide()) {
  813. return;
  814. }
  815. $item = _this.core.getSlideItem(_this.core.index);
  816. if ((_this.$LG(e.target).hasClass('lg-item') ||
  817. $item.get().contains(e.target)) &&
  818. e.targetTouches.length === 1 &&
  819. _this.core.outer.hasClass('lg-zoomed')) {
  820. e.preventDefault();
  821. startTime = new Date();
  822. _this.core.touchAction = 'zoomSwipe';
  823. _LGel = _this.core
  824. .getSlideItem(_this.core.index)
  825. .find('.lg-img-wrap')
  826. .first();
  827. var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue));
  828. allowY = dragAllowedAxises.allowY;
  829. allowX = dragAllowedAxises.allowX;
  830. if (allowX || allowY) {
  831. startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue));
  832. }
  833. possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue);
  834. // reset opacity and transition duration
  835. _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition');
  836. }
  837. });
  838. this.core.$inner.on('touchmove.lg', function (e) {
  839. if (e.targetTouches.length === 1 &&
  840. _this.core.touchAction === 'zoomSwipe' &&
  841. (_this.$LG(e.target).hasClass('lg-item') ||
  842. $item.get().contains(e.target))) {
  843. e.preventDefault();
  844. _this.core.touchAction = 'zoomSwipe';
  845. endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue));
  846. var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
  847. if (Math.abs(endCoords.x - startCoords.x) > 15 ||
  848. Math.abs(endCoords.y - startCoords.y) > 15) {
  849. isMoved = true;
  850. _this.setZoomSwipeStyles(_LGel, distance);
  851. }
  852. }
  853. });
  854. this.core.$inner.on('touchend.lg', function (e) {
  855. if (_this.core.touchAction === 'zoomSwipe' &&
  856. (_this.$LG(e.target).hasClass('lg-item') ||
  857. $item.get().contains(e.target))) {
  858. _this.core.touchAction = undefined;
  859. _this.core.outer.removeClass('lg-zoom-dragging');
  860. if (!isMoved) {
  861. return;
  862. }
  863. isMoved = false;
  864. endTime = new Date();
  865. var touchDuration = endTime.valueOf() - startTime.valueOf();
  866. _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue);
  867. }
  868. });
  869. };
  870. Zoom.prototype.zoomDrag = function () {
  871. var _this = this;
  872. var startCoords = {};
  873. var endCoords = {};
  874. var isDragging = false;
  875. var isMoved = false;
  876. // Allow x direction drag
  877. var allowX = false;
  878. // Allow Y direction drag
  879. var allowY = false;
  880. var startTime;
  881. var endTime;
  882. var possibleSwipeCords;
  883. var _LGel;
  884. this.core.outer.on('mousedown.lg.zoom', function (e) {
  885. // Allow zoom only on image
  886. if (!_this.isImageSlide()) {
  887. return;
  888. }
  889. var $item = _this.core.getSlideItem(_this.core.index);
  890. if (_this.$LG(e.target).hasClass('lg-item') ||
  891. $item.get().contains(e.target)) {
  892. startTime = new Date();
  893. _LGel = _this.core
  894. .getSlideItem(_this.core.index)
  895. .find('.lg-img-wrap')
  896. .first();
  897. var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue));
  898. allowY = dragAllowedAxises.allowY;
  899. allowX = dragAllowedAxises.allowX;
  900. if (_this.core.outer.hasClass('lg-zoomed')) {
  901. if (_this.$LG(e.target).hasClass('lg-object') &&
  902. (allowX || allowY)) {
  903. e.preventDefault();
  904. startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
  905. possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue);
  906. isDragging = true;
  907. // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
  908. _this.core.outer.get().scrollLeft += 1;
  909. _this.core.outer.get().scrollLeft -= 1;
  910. _this.core.outer
  911. .removeClass('lg-grab')
  912. .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging');
  913. // reset opacity and transition duration
  914. }
  915. }
  916. }
  917. });
  918. this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) {
  919. if (isDragging) {
  920. isMoved = true;
  921. endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
  922. var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
  923. _this.setZoomSwipeStyles(_LGel, distance);
  924. }
  925. });
  926. this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) {
  927. if (isDragging) {
  928. endTime = new Date();
  929. isDragging = false;
  930. _this.core.outer.removeClass('lg-zoom-dragging');
  931. // Fix for chrome mouse move on click
  932. if (isMoved &&
  933. (startCoords.x !== endCoords.x ||
  934. startCoords.y !== endCoords.y)) {
  935. endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
  936. var touchDuration = endTime.valueOf() - startTime.valueOf();
  937. _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue);
  938. }
  939. isMoved = false;
  940. }
  941. _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
  942. });
  943. };
  944. Zoom.prototype.closeGallery = function () {
  945. this.resetZoom();
  946. };
  947. Zoom.prototype.destroy = function () {
  948. // Unbind all events added by lightGallery zoom plugin
  949. this.$LG(window).off(".lg.zoom.global" + this.core.lgId);
  950. this.core.LGel.off('.lg.zoom');
  951. this.core.LGel.off('.zoom');
  952. clearTimeout(this.zoomableTimeout);
  953. this.zoomableTimeout = false;
  954. };
  955. return Zoom;
  956. }());
  957. export default Zoom;
  958. //# sourceMappingURL=lg-zoom.es5.js.map