Search code examples
flutterzoominginteractive

How to set InteractiveViewer initial zoom level


I am using InteractiveViewer to display a video. It is working properly. But I want set initial zoom level.

Is there a way to do this?

return InteractiveViewer(
  minScale: 1,
  maxScale: 4,
  constrained: false,
  child: Container(
    color: Colors.red,
    width: 320,
    height: 180,
    child: widget.remoteVideoRenderer(),
  ),
);

Solution

  • I was able to do this, with varying levels of success, like so (credit to @pskink for pointing me in the right direction):

      final viewTransformationController = TransformationController();
    
      @override
      void initState() {
        final zoomFactor = 2.0;
        final xTranslate = 300.0;
        final yTranslate = 300.0;
        viewTransformationController.value.setEntry(0, 0, zoomFactor);
        viewTransformationController.value.setEntry(1, 1, zoomFactor);
        viewTransformationController.value.setEntry(2, 2, zoomFactor);
        viewTransformationController.value.setEntry(0, 3, -xTranslate);
        viewTransformationController.value.setEntry(1, 3, -yTranslate);
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return InteractiveViewer(
                  transformationController: viewTransformationController,
                  minScale: 0.1,
                  maxScale: 6,
                  child: // ....
        );
      }
    
    

    viewTransformationController.value is a 4x4 matrix that is applied to the view, it encodes the translations/rotations/scaling. The representation of these transformations in the matrix is probably documented somewhere (and/or just standard from projective/affine geometry), but I couldn't find them, so I just printed them out while zooming/panning until the roles of each entry became clear.

    If you just set the zoom factor to 2 and don't translate, you'll be zoomed-in on the top-left corner of the widget.

    Note that you cannot access the windows dimensions in the initState() method using MediaQuery.of(context), which is somewhat inconvenient if you want to e.g. zoom in on the middle of the window. I haven't found a good way to do that yet.