pskink/matrix_gesture_detector

How to scale only in 1 direction ?

Opened this issue · 2 comments

I want to scale only in x direction but currently the scale gesture scales in both x and y like zooming. But i want stretch operation. How to solve this issue ?

I think I had similar case. What I did was

  1. Extract the decomposed Matrix4 (has the translation, rotation and scale) using the MatrixGestureDetector.decomposeToValues method
  2. Recreate the Vector3 of Scale with the 1.0 for the Y value and the scaled X value (if I want to stretch along the X axis).
  3. Reassign all the values back with Matrix4.compose method.

See the code example below:

    final decomposedMatrix4 = MatrixGestureDetector.decomposeToValues(gestureMatrix);
    final translation = Vector3(decomposedMatrix4.translation.dx,
        decomposedMatrix4.translation.dy, 0.0);
    final scale = Vector3(decomposedMatrix4.scale, 1.0, 0.0);
    final noRotation = Quaternion.identity();
    final xStretchedMatrix = Matrix4.compose(translation, noRotation, scale);

The gestureMatrix is the one passed by the onMatrixUpdate Callback, which is the 'm' value in the example given by the author. Then you just use this xStretchedMatrix to pass to your CanvasPainter (if you are using this) or whatever method you use.

Hope this helps.

How can i set the minimum scale?

I am facing the issue
my situation is that one image in stack is fixed but inside image i have another image which is move, scale, translate etc using MatrixGesture detector

the minimal code is

set initial Matrix4 value,
final ValueNotifier notifier = ValueNotifier(Matrix4.identity());

when i zoom in using two finger the image is invisible
the rest of the code is below

MatrixGestureDetector(
focalPointAlignment: Alignment.center,
onMatrixUpdate: (m, tm, sm, rm) {
notifier.value = m;

            },
            child: RepaintBoundary(
              key: saverProvider.globalKey,
              child: Stack(
                alignment: Alignment.center,
                children: <Widget>[
                  ///
                  FutureBuilder<ui.Image>(
                    future: getImage(),
                    builder: (BuildContext context,
                        AsyncSnapshot<ui.Image> snapshot) {
                      if (snapshot.hasData) {
                       
                        if (snapshot.hasData &&
                            snapshot.connectionState ==
                                ConnectionState.waiting) {
                          return const SizedBox.shrink();
                        }
                        return AnimatedBuilder(
                          animation: notifier,
                          builder: (ctx, childWidget) {
                            return Transform(
                              alignment: FractionalOffset.center,
                              transform: notifier.value,
                              filterQuality: FilterQuality.high,
                              child: Align(
                                alignment: Alignment.center,
                                child: FittedBox(
                                  child: SizedBox(
                                    width: snapshot.data?.width.toDouble(),
                                    height:
                                        snapshot.data?.height.toDouble(),
                                    child: Transform.scale(
                                        scaleX: flipScale.toDouble(),
                                        scaleY:
                                            verticalFlipScale.toDouble(),
                                        alignment: Alignment.center,
                                        child:
                                          
                                            Container(
                                          width: 1.sw,
                                          decoration: BoxDecoration(
                                            image: DecorationImage(
                                              fit: BoxFit.contain,
                                              filterQuality:
                                                  FilterQuality.medium,
                                              colorFilter:
                                                  ColorFilter.matrix(
                                                      filter ?? ORIGINAL),
                                              image: FileImage(
                                                File(context
                                                    .watch<HomeProvider>()
                                                    .imageFile!
                                                    .path),
                                              ),
                                            ),
                                          ),
                                        )
                                      
                                        ),
                                  ),
                                ),
                              ),
                            );
                          },
                        );
                       
                      } else {
                        return const Center();
                      }
                    },
                  ),
                  Align(
                    alignment: Alignment.center,
                    child: name.isEmpty
                        ? const SizedBox.shrink()
                       : img,
                  ),
                ],
              ),
            ),
          )

thanks in advance