flutter_zoomable_image icon indicating copy to clipboard operation
flutter_zoomable_image copied to clipboard

Image Zooms Out Too Far and Image Scrolls Out of Viewport

Open samvictor opened this issue 7 years ago • 1 comments

The user is able to zoom out until the image disappears. This fixed it for me:

I changed:

  void _handleScaleUpdate(Size size, ScaleUpdateDetails d) {
    double newZoom = _previousZoom * d.scale;
    bool tooZoomedIn = _image.width * _scale / newZoom <= size.width ||
        _image.height * _scale / newZoom <= size.height;
    
    if (tooZoomedIn) {
      return;
    }

to:

  void _handleScaleUpdate(Size size, ScaleUpdateDetails d) {
    double newZoom = _previousZoom * d.scale;
    bool tooZoomedIn = _image.width * _scale / newZoom <= size.width ||
        _image.height * _scale / newZoom <= size.height;
      
    // Too Zoomed Out
    if (newZoom < 0.9)
        newZoom = 0.9;
      
    if (tooZoomedIn) {
        return;
    }

where 0.9 is the "give" or "leeway" so that the image can zoom out a little.

Image Scrolls out of Viewport. I fixed this in the Horizontal direction, but not the vertical. In the same function, I changed:

// Ensure that item under the focal point stays in the same place despite zooming
    final Offset normalizedOffset =
        (_startingFocalPoint - _previousOffset) / _previousZoom;
    Offset newOffset = d.focalPoint / _scale - normalizedOffset * _zoom;
    
    setState(() {
      _zoom = newZoom;
      _offset = newOffset;
    });
  }

to this:

// Ensure that item under the focal point stays in the same place despite zooming
    final Offset normalizedOffset =
        (_startingFocalPoint - _previousOffset) / _previousZoom;
    Offset newOffset = d.focalPoint / _scale - normalizedOffset * _zoom;
    
    // Out of Bounds X]
    double give = 20.0;
    if (newOffset.dx > give/_scale) 
        newOffset = newOffset.scale(0.0, 1.0).translate(give/_scale, 0.0);  
    else if (newOffset.dx*_scale + size.width*_zoom < size.width - give)
        newOffset = newOffset.scale(0.0, 1.0).translate((size.width - size.width*_zoom - give)/_scale, 0.0);
      
    setState(() {
      _zoom = newZoom;
      _offset = newOffset;
    });
  }

Here the variable "give" is the padding around the picture when it moves to its extreme right or left. Feel free to incorporate this into your code. No attribution or anything necessary. Sorry I couldn't do any fancy animations, but maybe you can figure it out.

samvictor avatar Aug 29 '17 08:08 samvictor

If you've already got it in git, I'll merge whatever you send my way. Looks like this is a partial fix for #7. I can rework stuff after it's merged.

perlatus avatar Aug 31 '17 21:08 perlatus