Pinchazo de lienzo para ampliar el tema (punto de pivote)

Estoy dibujando líneas en una vista personalizada y añadido pan y función de zoom. El problema es que cuando hago zoom con dos dedos, los puntos medios se calculan correctamente, pero cuando hago matrix.scale(scaleFactor, scaleFactor, midX, midY ), el lienzo salta (traduce) al midX y midY que era antes.

Déjame entenderlo:

Inicializo el punto medio entre mis dedos con 0/0. Tan pronto como el segundo puntero está en la pantalla, calculo el punto medio e invalida el onDraw. A continuación, el dibujo salta (traduce) hasta el último punto mediano conocido y empieza a acercarse. No quiero que el dibujo se traduzca al punto medio en lugar de simplemente acercar al punto medio seleccionado.

Aquí están los fragmentos de código relevantes:

método onDraw

 private float startX = 0f; private float startY = 0f; private float translateX; private float translateY; private float previousTranslateX = 0f; private float previousTranslateY = 0f; private float midX = 0f; private float midY = 0f; ... public void onDraw(Canvas canvas) { super.onDraw(canvas); cx = canvas.getWidth(); cy = canvas.getHeight(); mat.reset(); canvas.save(); int count = 0; mat.postScale(scaleFactor, -scaleFactor, midX, midY); mat.postTranslate(translateX, translateY); canvas.setMatrix(mat); // draw stuff here... canvas.restore(); } 

método onTouch

 public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mode = DRAG; startX = event.getX() - previousTranslateX; startY = event.getY() - previousTranslateY; break; case MotionEvent.ACTION_MOVE: if (event.getPointerCount() > 1) { mode = ZOOM; } else { translateX = event.getX() - startX; translateY = event.getY() - startY; } break; case MotionEvent.ACTION_POINTER_DOWN: mode = NONE; getMidPoint(event); break; case MotionEvent.ACTION_UP: mode = NONE; previousTranslateX = translateX; previousTranslateY = translateY; break; case MotionEvent.ACTION_POINTER_UP: mode = DRAG; previousTranslateX = translateX; previousTranslateY = translateY; break; } detector.onTouchEvent(event); if ((mode == DRAG) || mode == ZOOM) { invalidate(); } return true; } 

cálculo del punto medio

 private void getMidPoint(MotionEvent event) { //get offset screensize -> canvas int offX = sx-cx; int offY = sy-cy; //get finger coordinates relative to offset f1x = event.getX(0)+offX; f1y = event.getY(0)+offY; f2x = event.getX(1)+offX; f2y = event.getY(1)+offY; midX = (f1x + f2x)/2; midY = (f1y + f2y)/2; //because my points are in a local coordinate system the screen coordinates need to be mapped to current canvas matrix Matrix m = new Matrix(mat); m.invert(m); float[] touch = new float[] { midX, midY }; m.mapPoints(touch); midX = touch[0]; midY = touch[1]; } 

Aquí están algunas imágenes: Esto es cuando la actividad comienza. El punto rojo marca la posición 0/0 del punto medio inicializado

Tan pronto como poner mis dedos donde están los puntos azules y empezar a hacer zoom:

este será el resultado. Esto sucede tan pronto como empiezo a hacer zoom.

¡Realmente apreciaría si alguien tiene una respuesta para mí! Gracias por adelantado.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.