UNPKG

lightgallery

Version:

lightGallery is a feature-rich, modular JavaScript gallery plugin for building beautiful image and video galleries for the web and the mobile

1,416 lines • 52.5 kB
(function(global, factory) {
  typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.lgZoom = factory());
})(this, function() {
  "use strict";/*!
 * lightgallery | 3.0.0 | October 9th 2026
 * http://www.lightgalleryjs.com/
 * Copyright (c) 2020 Sachin Neravath;
 * @license GPLv3
 */

  const SPRING_SETTLE_DAMPING = 1;
  const SPRING_BOUNCE_DAMPING = 0.82;
  const SPRING_NATURAL_FREQUENCY = 12;
  const DECELERATION_RATE = 0.995;
  function project(velocity, decelerationRate = DECELERATION_RATE) {
    return velocity * decelerationRate / (1 - decelerationRate);
  }
  function stepSpring(state, target, dtMs, {
    dampingRatio = SPRING_SETTLE_DAMPING,
    naturalFrequency = SPRING_NATURAL_FREQUENCY
  } = {}) {
    const t = dtMs / 1e3;
    const w0 = naturalFrequency;
    const zeta = Math.min(dampingRatio, 1);
    const x0 = state.position - target;
    const v0 = state.velocity * 1e3;
    const decay = Math.exp(-zeta * w0 * t);
    let x;
    let v;
    if (zeta < 1) {
      const wd = w0 * Math.sqrt(1 - zeta * zeta);
      const a = x0;
      const b = (v0 + zeta * w0 * x0) / wd;
      const cos = Math.cos(wd * t);
      const sin = Math.sin(wd * t);
      x = decay * (a * cos + b * sin);
      v = decay * ((b * wd - zeta * w0 * a) * cos - (a * wd + zeta * w0 * b) * sin);
    } else {
      const b = v0 + w0 * x0;
      x = decay * (x0 + b * t);
      v = decay * (b - w0 * (x0 + b * t));
    }
    return { position: target + x, velocity: v / 1e3 };
  }
  function isSpringSettled(state, target, restDelta = 0.3, restVelocity = 0.012) {
    return Math.abs(state.position - target) < restDelta && Math.abs(state.velocity) < restVelocity;
  }
  function parseImageSize(lgSize, viewportWidth) {
    if (!lgSize) {
      return void 0;
    }
    let size = lgSize;
    const responsiveSizes = lgSize.split(",");
    if (responsiveSizes[1]) {
      for (let i = 0; i < responsiveSizes.length; i++) {
        const candidate = responsiveSizes[i].trim();
        const responsiveWidth = parseInt(candidate.split("-")[2], 10);
        if (responsiveWidth > viewportWidth) {
          size = candidate;
          break;
        }
        if (i === responsiveSizes.length - 1) {
          size = candidate;
        }
      }
    }
    const parts = size.trim().split("-");
    const width = parseInt(parts[0], 10);
    const height = parseInt(parts[1], 10);
    if (!Number.isFinite(width) || !Number.isFinite(height)) {
      return void 0;
    }
    return { width, height };
  }
  function fitImageSize(size, containerWidth, containerHeight) {
    const maxWidth = Math.min(containerWidth, size.width);
    const maxHeight = Math.min(containerHeight, size.height);
    const ratio = Math.min(maxWidth / size.width, maxHeight / size.height);
    return { width: size.width * ratio, height: size.height * ratio };
  }
  const zoomDefaultIcons = {
    zoomIn: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="currentColor"><path transform="translate(0, 960) scale(1, -1)" d="M512 512.667h-86v-86h-42v86h-86v42h86v86h42v-86h86v-42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z"/></svg>',
    zoomOut: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="currentColor"><path transform="translate(0, 960) scale(1, -1)" d="M298 554.667h214v-42h-214v42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z"/></svg>',
    actualSize: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="currentColor"><path transform="translate(0, 960) scale(1, -1)" d="M384 853.334h426.667q53 0 90.5-37.5t37.5-90.5v-426.667q0-53-37.5-90.5t-90.5-37.5h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 53 37.5 90.5t90.5 37.5zM170.667 675.334v-547.333q0-17.667 12.5-30.167t30.167-12.5h547.333q-13.333-37.667-46.333-61.5t-74.333-23.833h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 41.333 23.833 74.333t61.5 46.333zM810.667 768h-426.667q-17.667 0-30.167-12.5t-12.5-30.167v-426.667q0-17.667 12.5-30.167t30.167-12.5h426.667q17.667 0 30.167 12.5t12.5 30.167v426.667q0 17.667-12.5 30.167t-30.167 12.5z"/></svg>'
  };
  function getPanBounds(imageWidth, imageHeight, containerWidth, containerHeight, scale) {
    return {
      maxX: Math.max(0, (imageWidth * scale - containerWidth) / 2),
      maxY: Math.max(0, (imageHeight * scale - containerHeight) / 2)
    };
  }
  function getActualSizeScale(naturalWidth, renderedWidth) {
    if (!renderedWidth) {
      return 2;
    }
    return naturalWidth / renderedWidth || 2;
  }
  function getPointZoomPan(point, prevPan, prevScale, newScale) {
    const ratio = newScale / prevScale;
    return {
      x: point.x - (point.x - prevPan.x) * ratio,
      y: point.y - (point.y - prevPan.y) * ratio
    };
  }
  function clampPanToStage(pan, bounds, stageBottomExtra) {
    const floorY = Math.min(-bounds.maxY + stageBottomExtra, bounds.maxY);
    return {
      x: Math.min(Math.max(pan.x, -bounds.maxX), bounds.maxX),
      y: Math.min(Math.max(pan.y, floorY), bounds.maxY)
    };
  }
  function getPinchPan(currentMid, startMid, startPan, startScale, scale) {
    const projected = getPointZoomPan(startMid, startPan, startScale, scale);
    return {
      x: projected.x + (currentMid.x - startMid.x),
      y: projected.y + (currentMid.y - startMid.y)
    };
  }
  function getPointerDistance(a, b) {
    return Math.sqrt(
      (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)
    );
  }
  const PINCH_UNDER_FRICTION = 0.15;
  const PINCH_OVER_FRICTION = 0.05;
  function getPinchScale(startDistance, currentDistance, startScale, maxScale, infiniteZoom, pinchToCloseArmed = false) {
    if (startDistance <= 0) {
      return startScale;
    }
    let scale = currentDistance / startDistance * startScale;
    if (scale < 1 && !pinchToCloseArmed) {
      scale = 1 + (scale - 1) * PINCH_UNDER_FRICTION;
    }
    const cap = Math.max(maxScale, 1);
    if (!infiniteZoom && scale > cap) {
      scale = cap + (scale - cap) * PINCH_OVER_FRICTION;
    }
    return scale;
  }
  function shouldCloseOnPinch(input) {
    return input.pinchToClose && input.closable && input.scale < 1 && input.maxGestureScale <= 1;
  }
  function parseSrcset(srcset) {
    const candidates = [];
    if (typeof srcset !== "string") {
      return candidates;
    }
    for (const entry of srcset.split(",")) {
      const parts = entry.trim().split(/\s+/);
      const url = parts[0];
      if (!url) {
        continue;
      }
      const descriptor = parts[1];
      if (!descriptor) {
        candidates.push({ url, density: 1 });
        continue;
      }
      const value = parseFloat(descriptor);
      if (Number.isNaN(value) || value <= 0) {
        continue;
      }
      if (descriptor.endsWith("w")) {
        candidates.push({ url, width: value });
      } else if (descriptor.endsWith("x")) {
        candidates.push({ url, density: value });
      }
    }
    return candidates;
  }
  function matchesMedia(media, viewport) {
    if (!media) {
      return true;
    }
    const condition = /^\(\s*(min|max)-width:\s*([\d.]+)px\s*\)$/.exec(
      media.trim()
    );
    if (!condition) {
      return false;
    }
    const bound = parseFloat(condition[2]);
    return condition[1] === "min" ? viewport.width >= bound : viewport.width <= bound;
  }
  function getActualSizeWidth(item, viewport, naturalWidth) {
    if (item.width) {
      const declared = parseFloat(item.width);
      if (!Number.isNaN(declared) && declared > 0) {
        return declared;
      }
    }
    let candidates = [];
    const sources = Array.isArray(item.sources) ? item.sources : [];
    for (const source of sources) {
      if (matchesMedia(source.media, viewport)) {
        candidates = parseSrcset(source.srcset);
        break;
      }
    }
    if (!candidates.length && item.srcset) {
      candidates = parseSrcset(item.srcset);
    }
    const widths = candidates.map((candidate) => candidate.width).filter((width) => width !== void 0);
    if (widths.length) {
      return Math.max(...widths);
    }
    const natural = parseImageSize(item.lgSize, viewport.width);
    if (natural && natural.width > 0) {
      return natural.width;
    }
    return naturalWidth;
  }
  const VELOCITY_WINDOW_MS = 100;
  const MIN_DISPLACEMENT = 1;
  const MIN_WINDOW_SPAN_MS = 5;
  function pushVelocitySample(samples, sample, windowMs = VELOCITY_WINDOW_MS) {
    return [...samples.filter((s) => sample.t - s.t <= windowMs), sample];
  }
  function getWindowedVelocity(samples, releaseTime, windowMs = VELOCITY_WINDOW_MS) {
    const recent = samples.filter((s) => releaseTime - s.t <= windowMs);
    if (recent.length < 2) {
      return { x: 0, y: 0 };
    }
    const first = recent[0];
    const last = recent[recent.length - 1];
    const dt = last.t - first.t;
    if (dt < MIN_WINDOW_SPAN_MS) {
      return { x: 0, y: 0 };
    }
    const dx = last.x - first.x;
    const dy = last.y - first.y;
    return {
      x: Math.abs(dx) > MIN_DISPLACEMENT ? dx / dt : 0,
      y: Math.abs(dy) > MIN_DISPLACEMENT ? dy / dt : 0
    };
  }
  function getRotatedVisualSize(width, height, transform) {
    if (!transform) {
      return { width, height };
    }
    const rotate = /rotate\((-?\d+(?:\.\d+)?)deg\)/.exec(transform);
    const scale = /scale3d\((-?\d+(?:\.\d+)?)/.exec(transform);
    const fit = (scale == null ? void 0 : scale[1]) ? Math.abs(parseFloat(scale[1])) : 1;
    const degrees = (rotate == null ? void 0 : rotate[1]) ? parseFloat(rotate[1]) : 0;
    const normalized = (degrees % 360 + 360) % 360;
    return normalized === 90 || normalized === 270 ? { width: height * fit, height: width * fit } : { width: width * fit, height: height * fit };
  }
  const MAX_FRAME_MS = 64;
  function runSprings(tracks, onFrame, onDone) {
    let raf = 0;
    let last = Date.now();
    const states = tracks.map((t) => ({
      position: t.from,
      velocity: t.velocity
    }));
    const frame = () => {
      const now = Date.now();
      const dt = Math.min(Math.max(now - last, 0), MAX_FRAME_MS);
      last = now;
      let settled = true;
      tracks.forEach((t, i) => {
        states[i] = stepSpring(states[i], t.target, dt, t);
        if (!isSpringSettled(states[i], t.target)) {
          settled = false;
        }
      });
      if (settled) {
        onFrame(tracks.map((t) => t.target));
        onDone == null ? void 0 : onDone();
        return;
      }
      onFrame(states.map((s) => s.position));
      raf = requestAnimationFrame(frame);
    };
    raf = requestAnimationFrame(frame);
    return () => cancelAnimationFrame(raf);
  }
  const zoomSettings = {
    scale: 1,
    zoom: true,
    infiniteZoom: true,
    actualSize: true,
    showZoomInOutIcons: false,
    actualSizeIcons: {
      zoomIn: "lg-zoom-in",
      zoomOut: "lg-zoom-out"
    },
    enableZoomAfter: 300
  };
  const lGEvents = {
    containerResize: "lgContainerResize",
    beforeOpen: "lgBeforeOpen",
    afterOpen: "lgAfterOpen",
    slideItemLoad: "lgSlideItemLoad",
    afterSlide: "lgAfterSlide",
    rotateLeft: "lgRotateLeft",
    rotateRight: "lgRotateRight",
    flipHorizontal: "lgFlipHorizontal",
    flipVertical: "lgFlipVertical"
  };
  var __defProp = Object.defineProperty;
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __spreadValues = (a, b) => {
    for (var prop in b || (b = {}))
      if (__hasOwnProp.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    if (__getOwnPropSymbols)
      for (var prop of __getOwnPropSymbols(b)) {
        if (__propIsEnum.call(b, prop))
          __defNormalProp(a, prop, b[prop]);
      }
    return a;
  };
  const ZOOM_TRANSITION_DURATION = 500;
  class Zoom {
    constructor(instance, $LG) {
      this.core = instance;
      this.$LG = $LG;
      this.settings = __spreadValues(__spreadValues({}, zoomSettings), this.core.settings);
      return this;
    }
    // Append Zoom controls. Actual size, Zoom-in, Zoom-out
    buildTemplates() {
      var _a, _b, _c, _d, _e, _f;
      const gestureButtons = this.core.settings.showGestureButtons !== false;
      let zoomIcons = gestureButtons && this.settings.showZoomInOutIcons ? `<button id="${this.core.getIdName(
        "lg-zoom-in"
      )}" type="button" aria-label="${(_b = (_a = this.settings.zoomPluginStrings) == null ? void 0 : _a.zoomIn) != null ? _b : this.core.settings.strings.zoomIn}" class="lg-zoom-in lg-icon"></button><button id="${this.core.getIdName(
        "lg-zoom-out"
      )}" type="button" aria-label="${(_d = (_c = this.settings.zoomPluginStrings) == null ? void 0 : _c.zoomOut) != null ? _d : this.core.settings.strings.zoomOut}" class="lg-zoom-out lg-icon"></button>` : "";
      if (gestureButtons && this.settings.actualSize) {
        zoomIcons += `<button id="${this.core.getIdName(
          "lg-actual-size"
        )}" type="button" aria-label="${(_f = (_e = this.settings.zoomPluginStrings) == null ? void 0 : _e.viewActualSize) != null ? _f : this.core.settings.strings.viewActualSize}" class="${this.settings.actualSizeIcons.zoomIn} lg-icon"></button>`;
      }
      this.core.outer.addClass("lg-use-transition-for-zoom");
      this.core.$toolbar.first().append(zoomIcons);
    }
    /**
     * @desc Enable zoom option only once the image is completely loaded
     * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted
     *
     * Zoom styles are defined under lg-zoomable CSS class.
     */
    enableZoom(event) {
      let _speed = this.settings.enableZoomAfter + event.detail.delay;
      if (this.$LG("body").first().hasClass("lg-from-hash") && event.detail.delay) {
        _speed = 0;
      } else {
        this.$LG("body").first().removeClass("lg-from-hash");
      }
      this.zoomableTimeout = setTimeout(() => {
        if (!this.isImageSlide(this.core.index)) {
          return;
        }
        this.core.getSlideItem(event.detail.index).addClass("lg-zoomable");
        if (event.detail.index === this.core.index) {
          this.setZoomEssentials();
        }
      }, _speed + 30);
    }
    enableZoomOnSlideItemLoad() {
      this.core.LGel.on(
        `${lGEvents.slideItemLoad}.zoom`,
        this.enableZoom.bind(this)
      );
    }
    getDragCords(e) {
      return {
        x: e.pageX,
        y: e.pageY
      };
    }
    getSwipeCords(e) {
      const x = e.touches[0].pageX;
      const y = e.touches[0].pageY;
      return {
        x,
        y
      };
    }
    getDragAllowedAxises(scale, scaleDiff) {
      if (!this.containerRect) {
        return {
          allowX: false,
          allowY: false
        };
      }
      const $image = this.core.getSlideItem(this.core.index).find(".lg-image").first().get();
      let height = 0;
      let width = 0;
      const rect = $image.getBoundingClientRect();
      if (scale) {
        const visual = this.getVisualImageSize(
          $image,
          $image.offsetWidth,
          $image.offsetHeight
        );
        height = visual.height * scale;
        width = visual.width * scale;
      } else if (scaleDiff) {
        height = rect.height + scaleDiff * rect.height;
        width = rect.width + scaleDiff * rect.width;
      } else if (this.core.currentImageSize) {
        const visual = this.getVisualImageSize(
          $image,
          this.core.currentImageSize.width,
          this.core.currentImageSize.height
        );
        height = visual.height * this.scale;
        width = visual.width * this.scale;
      } else {
        height = rect.height;
        width = rect.width;
      }
      const allowY = height > this.containerRect.height;
      const allowX = width > this.containerRect.width;
      return {
        allowX,
        allowY
      };
    }
    setZoomEssentials() {
      this.containerRect = this.core.$content.get().getBoundingClientRect();
    }
    /**
     * @desc Image zoom
     * Translate the wrap and scale the image to get better user experience
     *
     * @param {String} scale - Zoom decrement/increment value
     */
    zoomImage(scale, scaleDiff, reposition, resetToMax) {
      if (!this.containerRect || Math.abs(scaleDiff) <= 0) return;
      const offsetX = this.containerRect.width / 2 + this.containerRect.left;
      const offsetY = this.containerRect.height / 2 + this.containerRect.top + this.scrollTop;
      let originalX;
      let originalY;
      if (scale === 1) {
        this.positionChanged = false;
      }
      if (this.positionChanged) {
        const previousScale = this.scale - scaleDiff;
        originalX = previousScale ? this.left / previousScale : 0;
        originalY = previousScale ? this.top / previousScale : 0;
        this.pageX = offsetX - originalX;
        this.pageY = offsetY - originalY;
        this.positionChanged = false;
      }
      let x;
      let y;
      let _x = offsetX - this.pageX;
      let _y = offsetY - this.pageY;
      if (scale - scaleDiff > 1) {
        const scaleVal = (scale - scaleDiff) / Math.abs(scaleDiff);
        _x = (scaleDiff < 0 ? -_x : _x) + this.left * (scaleVal + (scaleDiff < 0 ? -1 : 1));
        _y = (scaleDiff < 0 ? -_y : _y) + this.top * (scaleVal + (scaleDiff < 0 ? -1 : 1));
        x = _x / scaleVal;
        y = _y / scaleVal;
      } else {
        const scaleVal = (scale - scaleDiff) * scaleDiff;
        x = _x * scaleVal;
        y = _y * scaleVal;
      }
      if (reposition) {
        const clamped = this.clampPinchPan({ x, y }, scale);
        x = clamped.x;
        y = clamped.y;
      }
      this.setZoomStyles({
        x,
        y,
        scale
      });
      this.left = x;
      this.top = y;
      if (resetToMax) {
        this.setZoomImageSize();
      }
    }
    resetImageTranslate(index) {
      if (!this.isImageSlide(index)) {
        return;
      }
      const $image = this.core.getSlideItem(index).find(".lg-image").first();
      this.imageReset = false;
      $image.removeClass(
        "reset-transition reset-transition-y reset-transition-x"
      );
      this.core.outer.removeClass("lg-actual-size");
      $image.css("width", "auto").css("height", "auto");
      setTimeout(() => {
        $image.removeClass("no-transition");
      }, 10);
    }
    setZoomImageSize(delay = ZOOM_TRANSITION_DURATION) {
      const $image = this.core.getSlideItem(this.core.index).find(".lg-image").first();
      setTimeout(() => {
        if (this.core.touchAction) {
          return;
        }
        const actualSizeScale = this.getCurrentImageActualSizeScale();
        if (this.scale >= actualSizeScale) {
          $image.addClass("no-transition");
          this.imageReset = true;
        }
      }, delay);
      setTimeout(() => {
        if (this.core.touchAction) {
          return;
        }
        const actualSizeScale = this.getCurrentImageActualSizeScale();
        if (this.scale >= actualSizeScale) {
          const dragAllowedAxises = this.getDragAllowedAxises(this.scale);
          const image = $image.get();
          const referenceWidth = this.getNaturalWidth(this.core.index);
          const referenceHeight = image.naturalWidth > 0 ? referenceWidth * image.naturalHeight / image.naturalWidth : image.naturalHeight;
          $image.css("width", referenceWidth + "px").css("height", referenceHeight + "px");
          this.core.outer.addClass("lg-actual-size");
          if (dragAllowedAxises.allowX && dragAllowedAxises.allowY) {
            $image.addClass("reset-transition");
          } else if (dragAllowedAxises.allowX && !dragAllowedAxises.allowY) {
            $image.addClass("reset-transition-x");
          } else if (!dragAllowedAxises.allowX && dragAllowedAxises.allowY) {
            $image.addClass("reset-transition-y");
          }
        }
      }, delay + 50);
    }
    /**
     * @desc apply scale3d to image and translate to image wrap
     * @param {style} X,Y and scale
     */
    setZoomStyles(style) {
      const $imageWrap = this.core.getSlideItem(this.core.index).find(".lg-img-wrap").first();
      const $image = this.core.getSlideItem(this.core.index).find(".lg-image").first();
      const $dummyImage = this.core.outer.find(".lg-current .lg-dummy-img").first();
      this.scale = style.scale;
      $image.css(
        "transform",
        "scale3d(" + style.scale + ", " + style.scale + ", 1)"
      );
      $dummyImage.css(
        "transform",
        "scale3d(" + style.scale + ", " + style.scale + ", 1)"
      );
      const transform = "translate3d(" + style.x + "px, " + style.y + "px, 0)";
      $imageWrap.css("transform", transform);
    }
    /**
     * @param index - Index of the current slide
     * @param event - event will be available only if the function is called on clicking/taping the imags
     */
    setActualSize(index, event) {
      if (this.zoomInProgress) {
        return;
      }
      this.zoomInProgress = true;
      const currentItem = this.core.galleryItems[this.core.index];
      this.resetImageTranslate(index);
      setTimeout(() => {
        if (!currentItem.src || this.core.outer.hasClass("lg-first-slide-loading")) {
          return;
        }
        const scale = this.getCurrentImageActualSizeScale();
        const prevScale = this.scale;
        if (this.core.outer.hasClass("lg-zoomed")) {
          this.scale = 1;
        } else {
          this.scale = this.getScale(scale);
        }
        this.setPageCords(event);
        this.beginZoom(this.scale);
        this.zoomImage(this.scale, this.scale - prevScale, true, true);
      }, 50);
      setTimeout(() => {
        this.core.outer.removeClass("lg-grabbing").addClass("lg-grab");
      }, 60);
      setTimeout(() => {
        this.zoomInProgress = false;
      }, ZOOM_TRANSITION_DURATION + 110);
    }
    getNaturalWidth(index) {
      const $image = this.core.getSlideItem(index).find(".lg-image").first();
      return getActualSizeWidth(
        this.core.galleryItems[index],
        {
          width: window.innerWidth
        },
        $image.get().naturalWidth
      );
    }
    getActualSizeScale(naturalWidth, width) {
      let scale;
      if (naturalWidth >= width) {
        scale = getActualSizeScale(naturalWidth, width);
      } else {
        scale = 1;
      }
      return scale;
    }
    getCurrentImageActualSizeScale() {
      var _a;
      const $image = this.core.getSlideItem(this.core.index).find(".lg-image").first();
      const image = $image.get();
      let width = (_a = this.core.currentImageSize) == null ? void 0 : _a.width;
      if (!width) {
        if (this.core.outer.hasClass("lg-actual-size")) {
          if (!this.containerRect) {
            this.setZoomEssentials();
          }
          const referenceWidth = this.getNaturalWidth(this.core.index);
          const referenceHeight = image.naturalWidth > 0 ? referenceWidth * image.naturalHeight / image.naturalWidth : image.naturalHeight;
          width = fitImageSize(
            {
              width: referenceWidth,
              height: referenceHeight
            },
            this.containerRect.width,
            this.containerRect.height
          ).width;
        } else {
          width = image.offsetWidth;
        }
      }
      const naturalWidth = this.getNaturalWidth(this.core.index) || width;
      return this.getActualSizeScale(naturalWidth, width);
    }
    getPageCords(event) {
      const cords = {};
      if (event) {
        cords.x = event.pageX || event.touches[0].pageX;
        cords.y = event.pageY || event.touches[0].pageY;
      } else {
        const containerRect = this.core.$content.get().getBoundingClientRect();
        cords.x = containerRect.width / 2 + containerRect.left;
        cords.y = containerRect.height / 2 + this.scrollTop + containerRect.top;
      }
      return cords;
    }
    setPageCords(event) {
      const pageCords = this.getPageCords(event);
      this.pageX = pageCords.x;
      this.pageY = pageCords.y;
    }
    manageActualPixelClassNames() {
      const $actualSize = this.core.getElementById("lg-actual-size");
      $actualSize.removeClass(this.settings.actualSizeIcons.zoomIn).addClass(this.settings.actualSizeIcons.zoomOut);
    }
    // If true, zoomed - in else zoomed out
    beginZoom(scale) {
      this.core.outer.removeClass("lg-zoom-drag-transition lg-zoom-dragging");
      if (scale > 1) {
        this.core.outer.addClass("lg-zoomed");
        this.manageActualPixelClassNames();
      } else {
        this.resetZoom();
      }
      return scale > 1;
    }
    getScale(scale) {
      const actualSizeScale = this.getCurrentImageActualSizeScale();
      if (scale < 1) {
        scale = 1;
      } else if (scale > actualSizeScale) {
        scale = actualSizeScale;
      }
      return scale;
    }
    init() {
      this.core.registerDefaultIcons(zoomDefaultIcons);
      if (!this.settings.zoom) {
        return;
      }
      this.buildTemplates();
      this.enableZoomOnSlideItemLoad();
      let tapped = null;
      this.core.outer.on("dblclick.lg", (event) => {
        if (!this.$LG(event.target).hasClass("lg-image")) {
          return;
        }
        this.setActualSize(this.core.index, event);
      });
      this.core.outer.on("touchstart.lg", (event) => {
        const $target = this.$LG(event.target);
        if (event.touches.length === 1 && $target.hasClass("lg-image")) {
          if (!tapped) {
            tapped = setTimeout(() => {
              tapped = null;
            }, 300);
          } else {
            clearTimeout(tapped);
            tapped = null;
            event.preventDefault();
            this.setActualSize(this.core.index, event);
          }
        }
      });
      this.core.LGel.on(
        `${lGEvents.containerResize}.zoom ${lGEvents.rotateRight}.zoom ${lGEvents.rotateLeft}.zoom ${lGEvents.flipHorizontal}.zoom ${lGEvents.flipVertical}.zoom`,
        () => {
          if (!this.core.lgOpened || !this.isImageSlide(this.core.index) || this.core.touchAction) {
            return;
          }
          this.stopZoomSpring();
          const _LGel = this.core.getSlideItem(this.core.index).find(".lg-img-wrap").first();
          this.top = 0;
          this.left = 0;
          this.setZoomEssentials();
          this.setZoomSwipeStyles(_LGel, { x: 0, y: 0 });
          this.positionChanged = true;
        }
      );
      this.$LG(window).on(`scroll.lg.zoom.global${this.core.lgId}`, () => {
        if (!this.core.lgOpened) return;
        this.scrollTop = this.$LG(window).scrollTop();
      });
      this.core.getElementById("lg-zoom-out").on("click.lg", () => {
        if (!this.isImageSlide(this.core.index)) {
          return;
        }
        let timeout = 0;
        if (this.imageReset) {
          this.resetImageTranslate(this.core.index);
          timeout = 50;
        }
        setTimeout(() => {
          let scale = this.scale - this.settings.scale;
          if (scale < 1) {
            scale = 1;
          }
          this.beginZoom(scale);
          this.zoomImage(
            scale,
            -this.settings.scale,
            true,
            !this.settings.infiniteZoom
          );
        }, timeout);
      });
      this.core.getElementById("lg-zoom-in").on("click.lg", () => {
        this.zoomIn();
      });
      this.core.getElementById("lg-actual-size").on("click.lg", () => {
        this.setActualSize(this.core.index);
      });
      this.core.LGel.on(`${lGEvents.beforeOpen}.zoom`, () => {
        this.core.outer.find(".lg-item").removeClass("lg-zoomable");
      });
      this.core.LGel.on(`${lGEvents.afterOpen}.zoom`, () => {
        this.scrollTop = this.$LG(window).scrollTop();
        this.pageX = this.core.outer.width() / 2;
        this.pageY = this.core.outer.height() / 2 + this.scrollTop;
        this.scale = 1;
      });
      this.core.LGel.on(
        `${lGEvents.afterSlide}.zoom`,
        (event) => {
          const { prevIndex } = event.detail;
          this.scale = 1;
          this.positionChanged = false;
          this.zoomInProgress = false;
          this.resetZoom(prevIndex);
          this.resetImageTranslate(prevIndex);
          if (this.isImageSlide(this.core.index)) {
            this.setZoomEssentials();
          }
        }
      );
      this.zoomDrag();
      this.pinchZoom();
      this.zoomSwipe();
      this.zoomableTimeout = false;
      this.positionChanged = false;
      this.zoomInProgress = false;
    }
    zoomIn() {
      if (!this.isImageSlide(this.core.index)) {
        return;
      }
      let scale = this.scale + this.settings.scale;
      if (!this.settings.infiniteZoom) {
        scale = this.getScale(scale);
      }
      this.beginZoom(scale);
      this.zoomImage(
        scale,
        Math.min(this.settings.scale, scale - this.scale),
        true,
        !this.settings.infiniteZoom
      );
    }
    // Reset zoom effect
    resetZoom(index) {
      this.stopZoomSpring();
      this.core.outer.removeClass("lg-zoomed lg-zoom-drag-transition");
      const $actualSize = this.core.getElementById("lg-actual-size");
      const $item = this.core.getSlideItem(
        index !== void 0 ? index : this.core.index
      );
      $actualSize.removeClass(this.settings.actualSizeIcons.zoomOut).addClass(this.settings.actualSizeIcons.zoomIn);
      $item.find(".lg-img-wrap").first().removeAttr("style");
      $item.find(".lg-image").first().removeAttr("style");
      this.scale = 1;
      this.left = 0;
      this.top = 0;
      this.setPageCords();
    }
    /** Stop a running release spring; state stays at its live values. */
    stopZoomSpring() {
      if (this.cancelZoomSpring) {
        this.cancelZoomSpring();
        this.cancelZoomSpring = void 0;
      }
    }
    /**
     * Any gesture end must leave the image inside its pan bounds: a tap
     * interrupts a settling spring (stopZoomSpring at its touchstart),
     * and if it never turns into a drag nothing else re-clamps, the
     * fused pinch pan can legitimately be far outside mid-settle.
     * Springs home from wherever the interruption stopped it; a no-op
     * when already in bounds (the common tap).
     */
    settleIntoBounds() {
      this.setZoomEssentials();
      const rect = this.core.getSlideItem(this.core.index).find(".lg-image").first().get().getBoundingClientRect();
      const actualSizeScale = this.getCurrentImageActualSizeScale();
      const targetScale = this.settings.infiniteZoom ? Math.max(this.scale, 1) : Math.min(Math.max(this.scale, 1), Math.max(actualSizeScale, 1));
      const sizeRatio = this.scale > 0 ? targetScale / this.scale : 1;
      const width = rect.width * sizeRatio;
      const height = rect.height * sizeRatio;
      const { bottom } = this.core.mediaContainerPosition;
      const halfX = Math.abs(width - this.containerRect.width) / 2;
      const halfY = Math.abs(height - this.containerRect.height) / 2;
      const floorY = height > this.containerRect.height ? Math.min(-halfY + bottom, halfY) : -halfY;
      const targetX = Math.min(Math.max(this.left, -halfX), halfX);
      const targetY = Math.min(Math.max(this.top, floorY), halfY);
      if (Math.abs(targetX - this.left) < 1 && Math.abs(targetY - this.top) < 1 && Math.abs(targetScale - this.scale) < 1e-3) {
        return;
      }
      this.core.outer.addClass("lg-zoom-drag-transition lg-zoom-dragging");
      this.stopZoomSpring();
      this.cancelZoomSpring = runSprings(
        [
          { from: this.scale, velocity: 0, target: targetScale },
          { from: this.left, velocity: 0, target: targetX },
          { from: this.top, velocity: 0, target: targetY }
        ],
        ([scale, x, y]) => {
          this.left = x;
          this.top = y;
          this.setZoomStyles({ x, y, scale });
        },
        () => {
          this.cancelZoomSpring = void 0;
          this.core.outer.removeClass(
            "lg-zoom-dragging lg-zoom-drag-transition"
          );
          if (targetScale > 1 && targetScale >= Math.max(actualSizeScale, 1)) {
            this.setZoomImageSize(0);
          }
        }
      );
    }
    getTouchDistance(e) {
      return getPointerDistance(
        { x: e.touches[0].pageX, y: e.touches[0].pageY },
        { x: e.touches[1].pageX, y: e.touches[1].pageY }
      );
    }
    /**
     * Pinch midpoint relative to the stage centre, the focal anchor the
     * whole gesture projects through.
     */
    getPinchMidPoint(e) {
      const centerX = this.containerRect.width / 2 + this.containerRect.left;
      const centerY = this.containerRect.height / 2 + this.containerRect.top + this.scrollTop;
      return {
        x: (e.touches[0].pageX + e.touches[1].pageX) / 2 - centerX,
        y: (e.touches[0].pageY + e.touches[1].pageY) / 2 - centerY
      };
    }
    /**
     * Clamp a pan into the stage-aware bounds at the given scale,
     * measured from the untransformed layout size (offset dimensions
     * ignore transforms, so this stays correct mid-gesture). Y matches
     * `getPossibleSwipeDragCords`: the vacated components strip belongs
     * to the stage, so the pan-up floor sits where the image's bottom
     * edge meets the SCREEN bottom, not the content box.
     */
    /**
     * Bounds-relevant size of the image: layout offsets swapped and
     * shrunk by the rotate plugin's wrapper transform when present,
     * at 90°/270° the visual width runs along the layout height, and
     * offsets don't see transforms.
     */
    getVisualImageSize($image, width, height) {
      const rotateWrap = $image.closest(".lg-img-rotate");
      return getRotatedVisualSize(width, height, rotateWrap == null ? void 0 : rotateWrap.style.transform);
    }
    clampPinchPan(pan, scale) {
      const $image = this.core.getSlideItem(this.core.index).find(".lg-image").first().get();
      const visual = this.getVisualImageSize(
        $image,
        $image.offsetWidth,
        $image.offsetHeight
      );
      const bounds = getPanBounds(
        visual.width,
        visual.height,
        this.containerRect.width,
        this.containerRect.height,
        scale
      );
      return clampPanToStage(
        pan,
        bounds,
        this.core.mediaContainerPosition.bottom
      );
    }
    pinchZoom() {
      let startDist = 0;
      let pinchStarted = false;
      let initScale = 1;
      let startMaxScale = 1;
      let startPan = { x: 0, y: 0 };
      let startMid = { x: 0, y: 0 };
      let maxGestureScale = 1;
      let lastMid = { x: 0, y: 0 };
      let midSamples = [];
      let $item = this.core.getSlideItem(this.core.index);
      this.core.outer.on("touchstart.lg", (e) => {
        $item = this.core.getSlideItem(this.core.index);
        if (!this.isImageSlide(this.core.index)) {
          return;
        }
        if (e.touches.length === 2) {
          e.preventDefault();
          if (this.core.outer.hasClass("lg-first-slide-loading")) {
            return;
          }
          this.stopZoomSpring();
          this.setZoomEssentials();
          initScale = this.scale || 1;
          startPan = { x: this.left, y: this.top };
          startMid = this.getPinchMidPoint(e);
          this.core.outer.addClass(
            "lg-zoom-drag-transition lg-zoom-dragging"
          );
          this.setPageCords(e);
          this.resetImageTranslate(this.core.index);
          startMaxScale = this.getCurrentImageActualSizeScale();
          this.core.touchAction = "pinch";
          startDist = this.getTouchDistance(e);
          maxGestureScale = initScale;
          lastMid = startMid;
          midSamples = [{ x: startMid.x, y: startMid.y, t: Date.now() }];
        }
      });
      this.core.$inner.on("touchmove.lg", (e) => {
        if (e.touches.length === 2 && this.core.touchAction === "pinch" && (this.$LG(e.target).hasClass("lg-item") || $item.get().contains(e.target))) {
          e.preventDefault();
          const endDist = this.getTouchDistance(e);
          const distance = startDist - endDist;
          if (!pinchStarted && Math.abs(distance) > 5) {
            pinchStarted = true;
          }
          if (pinchStarted) {
            const closeArmed = this.core.settings.pinchToClose && this.core.settings.closable && maxGestureScale <= 1;
            const _scale = getPinchScale(
              startDist,
              endDist,
              initScale,
              startMaxScale,
              this.settings.infiniteZoom,
              closeArmed
            );
            const scale = Math.round((_scale + Number.EPSILON) * 1e4) / 1e4;
            const mid = this.getPinchMidPoint(e);
            lastMid = mid;
            midSamples = pushVelocitySample(midSamples, {
              x: mid.x,
              y: mid.y,
              t: Date.now()
            });
            const pan = getPinchPan(
              mid,
              startMid,
              startPan,
              initScale,
              scale
            );
            this.left = pan.x;
            this.top = pan.y;
            this.setZoomStyles({ x: pan.x, y: pan.y, scale });
            maxGestureScale = Math.max(maxGestureScale, scale);
          }
        }
      });
      this.core.$inner.on("touchend.lg", (e) => {
        if (this.core.touchAction === "pinch" && (this.$LG(e.target).hasClass("lg-item") || $item.get().contains(e.target))) {
          pinchStarted = false;
          startDist = 0;
          if (shouldCloseOnPinch({
            scale: this.scale,
            maxGestureScale,
            pinchToClose: this.core.settings.pinchToClose,
            closable: this.core.settings.closable
          })) {
            this.core.outer.removeClass("lg-zoom-dragging");
            this.resetZoom();
            this.core.closeGallery();
          } else if (this.scale <= 1) {
            this.core.outer.removeClass("lg-zoomed");
            this.stopZoomSpring();
            this.cancelZoomSpring = runSprings(
              [
                { from: this.scale, velocity: 0, target: 1 },
                { from: this.left, velocity: 0, target: 0 },
                { from: this.top, velocity: 0, target: 0 }
              ],
              ([scale, x, y]) => {
                this.left = x;
                this.top = y;
                this.setZoomStyles({
                  x,
                  y,
                  scale
                });
              },
              () => {
                this.cancelZoomSpring = void 0;
                this.core.outer.removeClass("lg-zoom-dragging");
                this.resetZoom();
              }
            );
          } else {
            const actualSizeScale = startMaxScale;
            const targetScale = Math.min(
              this.scale,
              Math.max(actualSizeScale, 1)
            );
            const midVelocity = getWindowedVelocity(
              midSamples,
              Date.now()
            );
            const basePan = getPinchPan(
              lastMid,
              startMid,
              startPan,
              initScale,
              targetScale
            );
            const glide = {
              x: basePan.x + project(midVelocity.x),
              y: basePan.y + project(midVelocity.y)
            };
            const pan = this.clampPinchPan(glide, targetScale);
            this.positionChanged = true;
            this.manageActualPixelClassNames();
            this.core.outer.addClass("lg-zoomed");
            this.stopZoomSpring();
            this.cancelZoomSpring = runSprings(
              [
                {
                  from: this.scale,
                  velocity: 0,
                  target: targetScale
                },
                {
                  from: this.left,
                  velocity: midVelocity.x,
                  target: pan.x,
                  dampingRatio: pan.x !== glide.x ? SPRING_BOUNCE_DAMPING : 1
                },
                {
                  from: this.top,
                  velocity: midVelocity.y,
                  target: pan.y,
                  dampingRatio: pan.y !== glide.y ? SPRING_BOUNCE_DAMPING : 1
                }
              ],
              ([scale, x, y]) => {
                this.left = x;
                this.top = y;
                this.setZoomStyles({
                  x,
                  y,
                  scale
                });
              },
              () => {
                this.cancelZoomSpring = void 0;
                this.core.outer.removeClass(
                  "lg-zoom-dragging lg-zoom-drag-transition"
                );
                if (targetScale >= actualSizeScale) {
                  this.setZoomImageSize(0);
                }
              }
            );
          }
          this.core.touchAction = void 0;
        }
      });
    }
    touchendZoom(startCoords, endCoords, allowX, allowY, velocity) {
      const _LGel = this.core.getSlideItem(this.core.index).find(".lg-img-wrap").first();
      const possibleSwipeCords = this.getPossibleSwipeDragCords();
      const current = this.getZoomSwipeCords(
        startCoords,
        endCoords,
        allowX,
        allowY,
        possibleSwipeCords
      );
      const clampAxis = (value, min, max) => Math.min(Math.max(value, max), min);
      const targetX = allowX ? clampAxis(
        current.x + project(velocity.x),
        possibleSwipeCords.minX,
        possibleSwipeCords.maxX
      ) : this.left;
      const targetY = allowY ? clampAxis(
        current.y + project(velocity.y),
        possibleSwipeCords.minY,
        possibleSwipeCords.maxY
      ) : this.top;
      this.positionChanged = true;
      if (Math.abs(targetX - current.x) < 1 && Math.abs(targetY - current.y) < 1) {
        this.left = targetX;
        this.top = targetY;
        this.setZoomSwipeStyles(_LGel, { x: targetX, y: targetY });
        this.core.outer.removeClass(
          "lg-zoom-dragging lg-zoom-drag-transition"
        );
        return;
      }
      this.core.outer.addClass("lg-zoom-dragging");
      this.stopZoomSpring();
      this.cancelZoomSpring = runSprings(
        [
          {
            from: current.x,
            velocity: velocity.x,
            target: targetX,
            dampingRatio: targetX !== current.x + project(velocity.x) ? SPRING_BOUNCE_DAMPING : 1
          },
          {
            from: current.y,
            velocity: velocity.y,
            target: targetY,
            dampingRatio: targetY !== current.y + project(velocity.y) ? SPRING_BOUNCE_DAMPING : 1
          }
        ],
        ([x, y]) => {
          this.left = x;
          this.top = y;
          this.setZoomSwipeStyles(_LGel, { x, y });
        },
        () => {
          this.cancelZoomSpring = void 0;
          this.core.outer.removeClass(
            "lg-zoom-dragging lg-zoom-drag-transition"
          );
        }
      );
    }
    getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords) {
      const distance = {};
      if (allowY) {
        distance.y = this.top + (endCoords.y - startCoords.y);
        if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
          const diffMinY = possibleSwipeCords.minY - distance.y;
          distance.y = possibleSwipeCords.minY - diffMinY / 6;
        } else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
          const diffMaxY = distance.y - possibleSwipeCords.maxY;
          distance.y = possibleSwipeCords.maxY + diffMaxY / 6;
        }
      } else {
        distance.y = this.top;
      }
      if (allowX) {
        distance.x = this.left + (endCoords.x - startCoords.x);
        if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
          const diffMinX = possibleSwipeCords.minX - distance.x;
          distance.x = possibleSwipeCords.minX - diffMinX / 6;
        } else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
          const difMaxX = distance.x - possibleSwipeCords.maxX;
          distance.x = possibleSwipeCords.maxX + difMaxX / 6;
        }
      } else {
        distance.x = this.left;
      }
      return distance;
    }
    isBeyondPossibleLeft(x, minX) {
      return x >= minX;
    }
    isBeyondPossibleRight(x, maxX) {
      return x <= maxX;
    }
    isBeyondPossibleTop(y, minY) {
      return y >= minY;
    }
    isBeyondPossibleBottom(y, maxY) {
      return y <= maxY;
    }
    isImageSlide(index) {
      const currentItem = this.core.galleryItems[index];
      return this.core.getSlideType(currentItem) === "image";
    }
    getPossibleSwipeDragCords(scale) {
      const $image = this.core.getSlideItem(this.core.index).find(".lg-image").first();
      const imgRect = $image.get().getBoundingClientRect();
      let imageHeight = imgRect.height;
      let imageWidth = imgRect.width;
      if (scale) {
        imageHeight = imageHeight + scale * imageHeight;
        imageWidth = imageWidth + scale * imageWidth;
      }
      const { bottom } = this.core.mediaContainerPosition;
      const minY = (imageHeight - this.containerRect.height) / 2;
      const maxY = (this.containerRect.height - imageHeight) / 2 + bottom;
      const minX = (imageWidth - this.containerRect.width) / 2;
      const maxX = (this.containerRect.width - imageWidth) / 2;
      const possibleSwipeCords = {
        minY,
        maxY,
        minX,
        maxX
      };
      return possibleSwipeCords;
    }
    setZoomSwipeStyles(LGel, distance) {
      LGel.css(
        "transform",
        "translate3d(" + distance.x + "px, " + distance.y + "px, 0)"
      );
    }
    zoomSwipe() {
      let startCoords = {};
      let endCoords = {};
      let isMoved = false;
      let allowX = false;
      let allowY = false;
      let samples = [];
      let possibleSwipeCords;
      let _LGel;
      let $item = this.core.getSlideItem(this.core.index);
      this.core.$inner.on("touchstart.lg", (e) => {
        if (!this.isImageSlide(this.core.index)) {
          return;
        }
        $item = this.core.getSlideItem(this.core.index);
        if ((this.$LG(e.target).hasClass("lg-item") || $item.get().contains(e.target)) && e.touches.length === 1 && this.core.outer.hasClass("lg-zoomed")) {
          e.preventDefault();
          this.stopZoomSpring();
          isMoved = false;
          endCoords = {};
          const startPoint = this.getSwipeCords(e);
          samples = [{ x: startPoint.x, y: startPoint.y, t: Date.now() }];
          this.core.touchAction = "zoomSwipe";
          _LGel = this.core.getSlideItem(this.core.index).find(".lg-img-wrap").first();
          const dragAllowedAxises = this.getDragAllowedAxises(0);
          allowY = dragAllowedAxises.allowY;
          allowX = dragAllowedAxises.allowX;
          startCoords = this.getSwipeCords(e);
          possibleSwipeCords = this.getPossibleSwipeDragCords();
          this.core.outer.addClass(
            "lg-zoom-dragging lg-zoom-drag-transition"
          );
        }
      });
      this.core.$inner.on("touchmove.lg", (e) => {
        if (e.touches.length === 1 && this.core.touchAction === "zoomSwipe" && (this.$LG(e.target).hasClass("lg-item") || $item.get().contains(e.target))) {
          e.preventDefault();
          this.core.touchAction = "zoomSwipe";
          endCoords = this.getSwipeCords(e);
          samples = pushVelocitySample(samples, {
            x: endCoords.x,
            y: endCoords.y,
            t: Date.now()
          });
          const distance = this.getZoomSwipeCords(
            startCoords,
            endCoords,
            allowX,
            allowY,
            possibleSwipeCords
          );
          if (Math.abs(endCoords.x - startCoords.x) > 15 || Math.abs(endCoords.y - startCoords.y) > 15) {
            isMoved = true;
            this.setZoomSwipeStyles(_LGel, distance);
          }
        }
      });
      this.core.$inner.on("touchend.lg", (e) => {
        if (this.core.touchAction === "zoomSwipe" && (this.$LG(e.target).hasClass("lg-item") || $item.get().contains(e.target))) {
          e.preventDefault();
          this.core.touchAction = void 0;
          this.core.outer.removeClass("lg-zoom-dragging");
          if (!isMoved) {
            this.settleIntoBounds();
            return;
          }
          isMoved = false;
          this.touchendZoom(
            startCoords,
            endCoords,
            allowX,
            allowY,
            getWindowedVelocity(samples, Date.now())
          );
        }
      });
    }
    zoomDrag() {
      let startCoords = {};
      let endCoords = {};
      let isDragging = false;
      let isMoved = false;
      let allowX = false;
      let allowY = false;
      let dragSamples = [];
      let possibleSwipeCords;
      let _LGel;
      this.core.outer.on("mousedown.lg.zoom", (e) => {
        if (!this.isImageSlide(this.core.index)) {
          return;
        }
        const $item = this.core.getSlideItem(this.core.index);
        if (this.$LG(e.target).hasClass("lg-item") || $item.get().contains(e.target)) {
          if (this.core.outer.hasClass("lg-zoomed")) {
            this.stopZoomSpring();
          }
          dragSamples = [{ x: e.pageX, y: e.pageY, t: Date.now() }];
          _LGel = this.core.getSlideItem(this.core.index).find(".lg-img-wrap").first();
          const dragAllowedAxises = this.getDragAllowedAxises(0);
          allowY = dragAllowedAxises.allowY;
          allowX = dragAllowedAxises.allowX;
          if (this.core.outer.hasClass("lg-zoomed")) {
            if (this.$LG(e.target).hasClass("lg-object") && (allowX || allowY)) {
              e.preventDefault();
              startCoords = this.getDragCords(e);
              possibleSwipeCords = this.getPossibleSwipeDragCords();
              isDragging = true;
              this.core.outer.removeClass("lg-grab").addClass(
                "lg-grabbing lg-zoom-drag-transition lg-zoom-dragging"
              );
            }
          }
        }
      });
      this.$LG(window).on(
        `mousemove.lg.zoom.global${this.core.lgId}`,
        (e) => {
          if (isDragging) {
            isMoved = true;
            endCoords = this.getDragCords(e);
            dragSamples = pushVelocitySample(dragSamples, {
              x: endCoords.x,
              y: endCoords.y,
              t: Date.now()
            });
            const distance = this.getZoomSwipeCords(
              startCoords,
              endCoords,
              allowX,
              allowY,
              possibleSwipeCords
            );
            this.setZoomSwipeStyles(_LGel, distance);
          }
        }
      );
      this.$LG(window).on(`mouseup.lg.zoom.global${this.core.lgId}`, (e) => {
        if (isDragging) {
          isDragging = false;
          this.core.outer.removeClass("lg-zoom-dragging");
          if (isMoved && (startCoords.x !== endCoords.x || startCoords.y !== endCoords.y)) {
            endCoords = this.getDragCords(e);
            this.touchendZoom(
              startCoords,
              endCoords,
              allowX,
              allowY,
              getWindowedVelocity(dragSamples, Date.now())
            );
          } else {
            this.settleIntoBounds();
          }
          isMoved = false;
        }
        this.core.outer.removeClass("lg-grabbing").addClass("lg-grab");
      });
    }
    closeGallery() {
      if (this.imageReset) {
        this.resetImageTranslate(this.core.index);
      }
      this.resetZoom();
      this.zoomInProgress = false;
    }
    destroy() {
      this.$LG(window).off(`.lg.zoom.global${this.core.lgId}`);
      this.core.LGel.off(".lg.zoom");
      this.core.LGel.off(".zoom");
      clearTimeout(this.zoomableTimeout);
      this.zoomableTimeout = false;
    }
  }
  return Zoom;
});
//# sourceMappingURL=lg-zoom.umd.js.map