Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Zoomable Widget

What I want to build is a widget that can make its child widget zoomable similar to the zoomable behavior.

Gestures I want to cover are

  1. Pinch To Zoom
  2. Double Tap to Zoom
  3. Tap to get the local Position of the widget

Here is my widget plan:

ZoomableWidget(
   child: // My custom Widget which should be zoomable.
)

Here is my current progress:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:vector_math/vector_math_64.dart';

class ZoomableWidget extends StatefulWidget {
  final Widget child;

  const ZoomableWidget({Key key, this.child}) : super(key: key);
  @override
  _ZoomableWidgetState createState() => _ZoomableWidgetState();
}

class _ZoomableWidgetState extends State<ZoomableWidget> {
  double _scale = 1.0;
  double _previousScale;
  @override
  Widget build(BuildContext context) {
    return ClipRect(
      child: GestureDetector(
        onScaleStart: (ScaleStartDetails details) {
          _previousScale = _scale;
        },
        onScaleUpdate: (ScaleUpdateDetails details) {
          setState(() {
            _scale = _previousScale * details.scale;
          });
        },
        onScaleEnd: (ScaleEndDetails details) {
          _previousScale = null;
        },
        child: Transform(
          transform: Matrix4.diagonal3(Vector3(_scale.clamp(1.0, 5.0),
              _scale.clamp(1.0, 5.0), _scale.clamp(1.0, 5.0))),
          alignment: FractionalOffset.center,
          child: widget.child,
        ),
      ),
    );
  }
}

The problem I have faced is, I cannot change the center of the pinch thus the image only zooms at (0,0) even after I zoom in the corner. Also, I cannot access horizontal drag and vertical drag to scroll the widget.

Thanks in advance.

like image 489
Aawaz Gyawali Avatar asked Jun 03 '19 08:06

Aawaz Gyawali


People also ask

How do I make widgets zoomable in flutter?

You only need to create an instance of the Zoom class in the child of your Scaffold or within the widget of your choice, within the child attribute, put the widget that you want to zoom in and the width and height of the canvas where it will be made zoom.

How do you make an image zoomable on flutter?

Flutter Photo View A simple zoomable image/content widget for Flutter. PhotoView enables images to become able to zoom and pan with user gestures such as pinch, rotate and drag. It also can show any widget instead of an image, such as Container, Text or a SVG.

How do you zoom in and zoom out on flutter?

Zooming and Panning in Flutter Maps (SfMaps) It is possible to zoom in and out for any layer to take a closer look at a specific region by pinching the map, scrolling the mouse wheel or track pad, or using the toolbar on the web.


2 Answers

As of Flutter 1.20, InteractiveViewer widget supports pan and Zoom out of the box.
To make any widget zoomable you need to simply wrap the child with InteractiveViewer.

@override
Widget build(BuildContext context) {
  return Center(
    child: InteractiveViewer(
      panEnabled: false, // Set it to false to prevent panning. 
      boundaryMargin: EdgeInsets.all(80),
      minScale: 0.5,
      maxScale: 4, 
      child: FlutterLogo(size: 200),
    ),
  );
}
like image 162
CopsOnRoad Avatar answered Oct 10 '22 01:10

CopsOnRoad


This is working perfectly now, thanks for the reference @pskink.

import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';

class ZoomableWidget extends StatefulWidget {
  final Widget child;

  const ZoomableWidget({Key key, this.child}) : super(key: key);
  @override
  _ZoomableWidgetState createState() => _ZoomableWidgetState();
}

class _ZoomableWidgetState extends State<ZoomableWidget> {
  Matrix4 matrix = Matrix4.identity();

  @override
  Widget build(BuildContext context) {
    return MatrixGestureDetector(
      onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
        setState(() {
          matrix = m;
        });
      },
      child: Transform(
        transform: matrix,
        child: widget.child,
      ),
    );
  }
}
like image 17
Aawaz Gyawali Avatar answered Oct 10 '22 02:10

Aawaz Gyawali