skip to Main Content

The use case is to display a zoomable / panable image with extra informations over it.

I’m using a Stack:

Stack(
  fit: StackFit.expand,
  clipBehavior: Clip.none,
  children: [
    const Image(
      image: AssetImage(
      'assets/some-photo.jpg'), // This may be large (eg. height 5000 x width 3000)
    ),
    Positioned( // The values are based on the photo dimension, in order to inform a specific area
      top: 2500,
      left: 1500,
      child: Container(
        color: Colors.red.withOpacity(0.5),
        width: 380,
        height: 380,
      ),
    ),
  ],
),

Thing is Stack resizes the children to fit its container:

  • the image is resized to container height
  • the Positioned is placed according to the container’s dimension, that is likely off screen considering the offset values.

In any case, positioned locations is desynchronized with the image underneath.

One solution I found was to make the Stack grow as much as needed. This way I ensure the underneath image is not shrinked, and the positionned elements remain correct:

OverflowBox(
  maxWidth: 3000, // Image width
  maxHeight: 5000, // Image height
  child:  Stack(
    // Stack content here
  ),
),

Now, if I try to zoom in the image, either with photo_view package or an InteractiveViewer() widget, it seems that OverflowBox() prevents the right computing of the content size.

I tried to wrap it with a SizedBox() with no success.

Would you have an idea to make the Stack zoomable while keeping the content positions synchronized?

2

Answers


  1. Chosen as BEST ANSWER

    I think some of my assumptions were wrong: Stack may not affect the size of its children, but the parents may.

    In my case, the InteractiveViewer() was adding constraints to the Stack(). This can be disabled through the constrained property set to false.

    So, here is a solution:

    InteractiveViewer(
        constrained: false, // <- This is the solution
        child: Stack(...), // No need for OverflowBox
    );
    

  2. Try InteractiveViewer for zoom & pan in Flutter (adjust minScale & maxScale).

      InteractiveViewer(
           minScale: 0.1, // Minimum zoom level (10% size)
           maxScale: 8.0, // Maximum zoom level (8x size)
           child: Stack(
             children: [...]
          )
        ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search