Search code examples
flutterdartrotationgesture

Flutter PhotoView - Rotation about the point between the fingers


I am using PhotoView (https://pub.dev/packages/photo_view) to showcase a map saved in gif format. I need the ability to zoom and rotate. My code:

class MapView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PhotoView(
      imageProvider: AssetImage("assets/maps/my_map.gif"),
      enableRotation: true,
      backgroundDecoration: BoxDecoration(
        color: Colors.white,
      ),
    );
  }
}

The problem is that the picture is rotated relative to the center of the picture, which is inconvenient. I want the rotation to be about a point between the two fingers that perform the rotation gesture (as in normal map applications). I have not found any information in the PhotoView documentation on how to fix this.

I hope for your support.


My final code (using matrix_gesture_detector):

class MapView extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MapViewState();
}

class _MapViewState extends State<MapView> {
  Matrix4 transform;

  @override
  void initState() {
    super.initState();
    transform = Matrix4.identity();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: MatrixGestureDetector(
        onMatrixUpdate: (m, tm, sm, rm) {
          setState(() {
            transform = m;
          });
        },
        child: Transform(
          transform: transform,
          child: Image.asset("assets/maps/my_map.gif"),
        ),
      ),
    );
  }
}

Solution

  • So there isn't anything I could find in Photo View that will help you achieve it, so use this package instead. Matrix gesture detector will work exactly the way you want.

    Sample code:

    class Test extends StatefulWidget {
    @override
    _TestState createState() => _TestState();
    }
    
    class _TestState extends State<Test> {
    
     Matrix4 transform;
     @override
     void initState() {
     super.initState();
     transform = Matrix4.identity();
     }
    
     @override
     Widget build(BuildContext context) {
        return Scaffold(
        body: Container(
           width: MediaQuery.of(context).size.width,
           height: MediaQuery.of(context).size.height,
           child: MatrixGestureDetector(
             onMatrixUpdate: (m, rs, ry, rx){
               setState(() {
                 transform = m;
           });
          },
          child: Container(
            transform: transform,
            height: 200,
            width: 200,
            color: Colors.blue,
          ),
        ),
      ),
       );
    }
    
    }
    

    You can place whatever you like in the container, in your case decoration Image.