question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature: Limit pan distance outside of canvas, e.g. maxPanRatio

See original GitHub issue

What problem does this feature solve? A user can pan the content outside of the canvas to the point that the content is no longer visible (and even multiple canvas-distances away from the origin), and it may be unintuitive for the user to get the content back inside the visible canvas.

Describe the solution you’d like An option to provide a max pan distance which would be a proportion of the pannable content, e.g. maxPanRatio: 0.9 representing 90% of the content can be outside of the canvas before panning in that direction is disabled.

Describe alternatives you’ve considered Unfortunately contain doesn’t appear to resolve this as we don’t want to limit the element to be inside the canvas, and outside didn’t seem to behave as expected for an element initially smaller than the canvas.

I did try contextually enabling and disabling contain: 'outside' depending on zoom level, but it doesn’t seem like that’s quite supported. That would also be a reasonable solution otherwise.

I have added logic that detects when the event.detail.x/event.detail.y values are outside of a specified range and calling pan to return them to the limit, but it feels a bit hacky and requires a bunch of un-throttled calculations.

Additional context Here’s a snippet of code to give an example of the approach I took. I found it pretty difficult to reason about, so pardon how verbose and yet indecipherable it is. Also, we’re in an untranspiled environment, so its var-city, among other things.


  function preventOverPanning(event) {
    var detail = event.detail;
    var x = detail.x;
    var y = detail.y;
    var scale = detail.scale;

    var mapRect = $map[0].getBoundingClientRect();
    var containerRect = $container[0].getBoundingClientRect();

    var scaledOffsetX = ((mapRect.width / scale) - mapRect.width) / 2;
    var scaledOffsetY = ((mapRect.height / scale) - mapRect.height) / 2;

    var relPosX = initRelPosX + scaledOffsetX;
    var relPosY = initRelPosY + scaledOffsetY;

    var gapX = (containerRect.width - mapRect.width) / 2;
    var gapY = (containerRect.height - mapRect.height) / 2;

    var maxPanRatio = 0.8; // Percentage of map to allow overflow.

    var panX = x * scale + relPosX - gapX;
    var maxPanX = mapRect.width * maxPanRatio + gapX;
    var isPannedTooFarX = Math.abs(panX) > maxPanX;

    var panY = y * scale + relPosY - gapY;
    var maxPanY = mapRect.height * maxPanRatio + gapY;
    var isPannedTooFarY = Math.abs(panY) > maxPanY;

    if (isPannedTooFarX || isPannedTooFarY) {
      var newX = x;
      var newY = y;

      if (isPannedTooFarX) {
        var signX = panX / Math.abs(panX);
        newX = (maxPanX * signX - relPosX + gapX) / scale;
      }
      if (isPannedTooFarY) {
        var signY = panY / Math.abs(panY);
        newY = (maxPanY * signY - relPosY + gapY) / scale;
      }

      panzoom.pan(newX, newY);
    }
  }

I do see that there have been issues related to this in the past. Would a PR be welcome, or is this a feature outside the scope of the native library?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:20
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
timmywilcommented, Jul 26, 2021

I think this have enough votes to implement, and we can use the ratio option instead of hard pixel amount. In other words, only the given amount of the panzoom element will be allowed outside the container.

2reactions
timmywilcommented, Apr 10, 2020

The contain: 'inside' option keeps the element inside the container, and contain: 'outside' is meant to be used with elements larger than the container. I didn’t consider a third option where panning would stop when based on a given ratio. You could also do it based on a given pixel amount regardless of scale.

Either way, I think this should go through the feature pipeline.

Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

jquery.panzoom - Bountysource
An option to provide a max pan distance which would be a proportion of the pannable content, e.g. maxPanRatio: 0.9 representing 90% of...
Read more >
How to limit panning distance in react three fiber MapControls
Show activity on this post. I'm using React Three Fiber and drei . I'm wondering how to limit the maximum panning distance with...
Read more >
Adjust rotation and canvas size in Photoshop - Adobe Support
This document outlines the different methods you can use to adjust your image's cropping, rotation, and canvas size.
Read more >
Zoom or pan the canvas in Motion - Apple Support
In Motion, zoom in on the canvas to allow precision alignment and placement of objects, or zoom out to get a sense of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found