JSFiddle - React, Tailwind, and code Playground

Fliplet.UI.PanZoom Library with Hammer.js

by Hugo Carneiro

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<div class="floorplan-component-wrapper">
  <div class="floor-wrapper-holder">
    <div class="floor-wrapper">
      <div class="floor-container">
        <img class="floor-image" src="https://api.fliplet.com/v1/media/files/220814/contents/floorplanEmpty.png?auth_token=eu--session--ced758f07107ee6446d32a2dae54c10c-463-892-9416&" />
      </div>
    </div>
  </div>
</div>

CSS

.floorplan-component-wrapper {
  position: relative;
  width: 100%;
  height: 100vh;
}

.floor-wrapper-holder {
  width: 100%;
  height: 100%;
}

.floor-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: none;
}

.floor-wrapper.active {
  display: block;
}

.floor-container {
  position: relative;
  transform-origin: 0px 0px 0px;
}

.fl-zoomIn,
.fl-zoomOut {
  position: absolute;
  right: 5px;
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #ffffff;
  background-color: #333333;
  border-radius: 50%;
  cursor: pointer;
}

.fl-zoomIn {
  bottom: 50px;
}

.fl-zoomOut {
  bottom: 5px;
}

.fl-zoomIn.off,
.fl-zoomOut.off {
  opacity: 0.1;
  cursor: default;
  pointer-events: none;
}

.floor-container img {
  max-width: none;
  width: 100%;
  height: auto;
}

.marker {
  position: absolute !important;
  z-index: 9;
  top: 150px;
  left: 150px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.marker .active-state {
  display: none;
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  pointer-events: none;
  transform: translate3d(-50%, -50%, 0);
}

.marker.active .active-state {
  display: block;
  -webkit-animation: pulse 1.2s ease-out infinite none;
  animation: pulse 1.2s ease-out infinite none;
}

@keyframes pulse {
  0% {
    transform: translate3d(-50%, -50%, 0) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate3d(-50%, -50%, 0) scale(3);
    opacity: 0;
  }
}

JavaScript

var Fliplet = Fliplet || {};
Fliplet.UI = Fliplet.UI || {};

function createNewPanZoomInstance(selector, options) {
  var flPanZoom = this;
  var defaults = {
    baseZoom: 1,
    doubleTapZoom: 2,
    minZoom: 1,
    maxZoom: 4,
    animDuration: 0.1,
    force3D: true,
    zoomStep: 0.5,
    allowDrag: true,
    allowZoom: true,
    allowMouseWheelZoom: true,
    allowPinchZoom: true,
    showZoomControls: true
  };

  flPanZoom.options = _.extend({}, defaults, options);
  var jFlPanZoom = $(flPanZoom);

  // VARS
  var baseZoom = flPanZoom.options.baseZoom;
  var doubleTapZoom = flPanZoom.options.doubleTapZoom;
  var maxZoom = flPanZoom.options.maxZoom;
  var minZoom = flPanZoom.options.minZoom;
  var animDuration = flPanZoom.options.animDuration;
  var force3D = flPanZoom.options.force3D;
  var zoomStep = flPanZoom.options.zoomStep;
  var allowMouseWheelZoom = flPanZoom.options.allowMouseWheelZoom;
  var allowDrag = flPanZoom.options.allowDrag;
  var allowZoom = flPanZoom.options.allowZoom;
  var allowPinchZoom = flPanZoom.options.allowPinchZoom;
  var showZoomControls = flPanZoom.options.showZoomControls;

  var $target = getTarget();
  var markers = [];
  var multiPoints = (navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1)
    || (navigator.maxTouchPoints && navigator.maxTouchPoints > 1);
  var panTouchAction = 'pan-x pan-y';
  var hammerInstance;
  var curElem = null;
  var parentElem = null;
  var image;
  var elemPosX = 0;
  var elemPosY = 0;
  var curX = 0;
  var curY = 0;
  var oldX = 0;
  var centerX = 0;
  var centerY = 0;
  var endZoom = 1;
  var curZoom = 1;
  var zoomComplete = true;
  var zoomPointX = 0.5;
  var zoomPointY = 0.5;
  var curWidth = 0;
  var curHeight = 0;
  var oldWidth = 0;
  var oldHeight = 0;
  var elemWidth = 0;
  var elemHeight = 0;
  var oldElemWidth = 0;
  var oldElemHeight = 0;
  var elemLeft = 0;
  var elemTop = 0;
  var holderWidth = 0;
  var holderHeight = 0;
  var oldHolderWidth = 0;
  var oldHolderHeight =...