react-native-awesome-gallery icon indicating copy to clipboard operation
react-native-awesome-gallery copied to clipboard

Scale / Pan Improvement Ideas

Open JacobJaffe opened this issue 10 months ago • 5 comments

Hello! First off, this library is amazing. Thank you!

In mirroring native behavior on iOS, I'd like to have panning lock horizontally / vertically when zoomed in, if the zoom still fully shows the image fully on the reverse axis. For example, when zooming in on a portrait image, I'd like to prevent vertical panning until the image exceeds the container (screen).

This kinda occurs in this library, but only when not zoomed in. (like for swipe-down behavior).

In a similar vein, it would be really cool if double-tapping could automatically zoom to constrain the image fully in the cross-dimension (maybe only if the image is within a reasonable aspect ratio). This would mirror native behavior as well, and probably under-the-hood use the same kinda calculations to determine if the image is locked-in-frame on a single dimension.

I'm happy to take a stab at implementing this if this sounds reasonable.

JacobJaffe avatar Jan 10 '25 22:01 JacobJaffe

Here's an example of what I mean. See how in the native photos app, scrolling is locked horizontally while the entire height of the image is already in frame. Very smooth!

https://github.com/user-attachments/assets/5cbd7567-d2be-4ba7-acb1-9cd7b8412c2c

JacobJaffe avatar Jan 10 '25 22:01 JacobJaffe

Were you able to figure this out @JacobJaffe?

jonluca avatar Apr 07 '25 22:04 jonluca

Were you able to figure this out @JacobJaffe?

I haven't attempted to do the axis locking yet.

I did get automatic zooming to the full view working, which can be done simply just by calculating the ideal full size zoom and using it as the prop.

JacobJaffe avatar Apr 08 '25 02:04 JacobJaffe

This is how I do that:

const useDoubleTapScale = (aspect: number) => {
  const dimensions = useDimensions();
  const phoneAspect = dimensions.screen.width / dimensions.screen.height;

  // When the image is proportionally taller than the phone screen, 
  // this doesn't work, so we just zoom to 3:
  if (aspect < phoneAspect) return 3;

  // Otherwise, we zoom such that the height of the image is the height of the screen:
  const scale = aspect / phoneAspect;

  return scale;
};

JacobJaffe avatar Apr 08 '25 02:04 JacobJaffe

@jonluca just took a stab at this, ended up being pretty straightforward. See #99

JacobJaffe avatar Apr 08 '25 04:04 JacobJaffe