Home > OS >  SVG Pan only when zoomed, bigger than viewport
SVG Pan only when zoomed, bigger than viewport

Time:01-30

Expected Outcome: Unable to pan SVG if it is not zoomed and SVG remains centered. When zoomed, allow panning to its boundaries.

Problem:

Using this solution How to only allow pan within the bounds of the original SVG, it still allows you to pan when SVG is not zoomed and when zoomed doesn't allow panning to all boundaries

Using this solution How to only allow pan within the bounds of the original SVG, panning while zoomed works as expected but when the SVG is not zoomed, once I try to pan it snaps to the right and to the bottom instead of remaining centered.

let beforePan

beforePan = function (oldPan, newPan) {
  let stopHorizontal = false,
    stopVertical = false,
    gutterWidth = this.getSizes().width,
    gutterHeight = this.getSizes().height,
    // Computed variables
    sizes = this.getSizes(),
    leftLimit = -((sizes.viewBox.x   sizes.viewBox.width) * sizes.realZoom)   gutterWidth,
    rightLimit = sizes.width - gutterWidth - (sizes.viewBox.x * sizes.realZoom),
    topLimit = -((sizes.viewBox.y   sizes.viewBox.height) * sizes.realZoom)   gutterHeight,
    bottomLimit = sizes.height - gutterHeight - (sizes.viewBox.y * sizes.realZoom)

  customPan = {}
  customPan.x = Math.max(leftLimit, Math.min(rightLimit, newPan.x))
  customPan.y = Math.max(topLimit, Math.min(bottomLimit, newPan.y))
  
  return customPan
}

let panZoomController = svgPanZoom('#map', {
  fit: 1,
  center: true,
  minZoom: 1,
  zoomScaleSensitivity: 0.5,
  beforePan: beforePan
});

The SVG (map) is inside a content div which is inside a wrapper div:

.wrapper {
    margin: auto;
}

.content {
    background-color: silver;
    position: absolute;
    inset: 0 0 0 0;
}

#map {
    width: 100%;
    height: 100%;
    position: relative;
    display: block;
}

CodePudding user response:

After many hours and tries to make it work using only one calculation I decided to use a different calculation when the SVG was smaller than the viewport (no panning allowed). Code below:

beforePan = function (oldPan, newPan) {
  let stopHorizontal = false,
    stopVertical = false,
    sizes = this.getSizes(),
    customPan = {}

  if (sizes.viewBox.width * sizes.realZoom < sizes.width || sizes.viewBox.height * sizes.realZoom < sizes.height) {
    customPan.x = (window.visualViewport.width - (sizes.viewBox.width * sizes.realZoom)) / 2
    customPan.y = (window.visualViewport.height - (sizes.viewBox.height * sizes.realZoom)) / 2
    console.log(sizes.viewBox.width)
  } else {
    let gutterWidth = sizes.width,
    gutterHeight = sizes.height,
    leftLimit = -((sizes.viewBox.x   sizes.viewBox.width) * sizes.realZoom)   gutterWidth,
    rightLimit = sizes.width - gutterWidth - (sizes.viewBox.x * sizes.realZoom),
    topLimit = -((sizes.viewBox.y   sizes.viewBox.height) * sizes.realZoom)   gutterHeight,
    bottomLimit = sizes.height - gutterHeight - (sizes.viewBox.y * sizes.realZoom)

    customPan.x = Math.max(leftLimit, Math.min(rightLimit, newPan.x))
    customPan.y = Math.max(topLimit, Math.min(bottomLimit, newPan.y))
  }

  return customPan
}
  • Related