2

Is there any ways of implementing smooth pinch to zoom without using matrix?

I am building drawing app and I want it to have pinch to zoom.

I get pivot point for scaling with:

centerposX = mScaleDetector.getFocusX();
centerposY = mScaleDetector.getFocusY();

and for scaling then I use:

canvas.scale(scaleFactor, scaleFactor, centerposX, centerposY);

But the problem is that it immediately centers view at the pivot point and them zooms it, rather than using it as a guide for centering.

I've seen that this problem has been solved by using matrix, but I don't want to use them as I need to keep track of offsets, ZoomTranslations which are calculated from centerposX/Y and scaleFactor to put drawings where they belong on screen.

So is there any way to solve this pivot point problem smoothly?

Thanks!

user3482211
  • 446
  • 4
  • 17
  • how can Canvas.scale center a View? and what's wrong with the Matrix, i didn't understand your explanation... – pskink Sep 20 '14 at 18:14
  • I meant that on touch my viewport instantly jumps to point of touch. and i want to implement browser like pinch to zoom behaviour. And I don't want to use matrices because Drawing on scaled screen requires to keep track of lots of variables and I am not sure how i would handle them with matrixes. Anyways, if there isn't any solutions to solve this "jumping"behavior I will rewrite my code. – user3482211 Sep 20 '14 at 18:56
  • So, I've tried to make everything with matrix. Scaling works like a charm. But there is one problem, finger drawings once again are getting misplaced when they are drawn, also they are not scaled properly. – user3482211 Sep 20 '14 at 20:07
  • see my answer here: http://stackoverflow.com/questions/21633545/android-imageview-scaling-and-translating-issue, maybe it will be helpful – pskink Sep 20 '14 at 20:12
  • But my onDraw() methods draws not only bitmap, but also path,and bitmap, sadly drawPath() doesnt take matrix as argument and this is main reason why I cannot use Matrix. – user3482211 Sep 21 '14 at 14:55
  • use Canvas.concat() then – pskink Sep 21 '14 at 15:11

1 Answers1

3

After a week I understood that I need to use matrix and get absolute coordinates on the screen, so I used Gesture detector to set matrix scale

matrix.postScale(mScaleFactor, mScaleFactor, focusX, focusY);

In my onDraw method I used canvas.concat(matrix); so not only Bitmap, but WHOLE canvas get's matrix transformation, and to get real screen coordinates I used a method i found on stack-overflow:

public float[] getAbsolutePosition(float Ax, float Ay) {
        matrix.getValues(m);

        float x = width - ((m[Matrix.MTRANS_X] - Ax) / m[Matrix.MSCALE_X])
                - (width - getTranslationX());

        float y = height - ((m[Matrix.MTRANS_Y] - Ay) / m[Matrix.MSCALE_X])
                - (height - getTranslationY());

        return new float[] { x, y };
    }

I call this every time in my onTouchEvent() method, supplying event.getX and event.getY() as arguments.

After that, everything is easy peasy, also because of this beautiful method I've got rid of ~4-5 variables which I had to use to find real touch location.

user3482211
  • 446
  • 4
  • 17