As I had mentioned before, we are able to pan and zoom but we still have problems: panning continues in all directions indefinitely, and our canvas "jerks" when we pan, lift our finger, and then pan again; it doesn't remember where we left off. Let's start with the second problem first, as it's the easier one. The reason that our canvas jerks is precisely because we don't keep track of where we left off, the last time we panned. This is fine if you're translating just once from the origin. However, if you want to translate again, you need to remember how much you've already translated by, otherwise the canvas is going to jerk back to where you place your finger again. To fix this problem, we use two new variables: previousTranslateX
and previousTranslateY
:
public class ZoomView extends View {
...
...
//These two variables keep track of the amount we translated the X and Y coordinates, the last time we
//panned.
private float previousTranslateX = 0f;
private float previousTranslateY = 0f;
...
...
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = DRAG;
//We assign the current X and Y coordinate of the finger to startX and startY minus the previously translated
//amount for each coordinates This works even when we are translating the first time because the initial
//values for these two variables is zero.
startX = event.getX() - previousTranslateX;
startY = event.getY() - previousTranslateY;
break;
case MotionEvent.ACTION_MOVE:
//We calculate the values of translateX and translateY by finding the difference between the X/Y coordinate
//and the starting X/Y coordinate. Since this event is fired every time the finger moves, we're constantly
//updating the values of these two coordinates
translateX = event.getX() - startX;
translateY = event.getY() - startY;
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = ZOOM;
break;
case MotionEvent.ACTION_UP:
mode = NONE;
//All fingers went up, so let's save the value of translateX and translateY into previousTranslateX and
//previousTranslateY
previousTranslateX = translateX;
previousTranslateY = translateY;
break;
case MotionEvent.ACTION_POINTER_UP:
mode = DRAG;
//This is not strictly necessary; we save the value of translateX and translateY into previousTranslateX
//and previousTranslateY when the second finger goes up
previousTranslateX = translateX;
previousTranslateY = translateY;
break;
}
...
...
}
}
I appreciate how clear you tried to explain everything. Thank you!
I want to do a “zoomable paint”, I mean a paint that I can zoom/zoom out and pan/drag the canvas and then draw on it.
I have a problem that I can’t solve: when I draw while the canvas is zoomed, I retrieve the X and Y coordinate and effectively drawing it on the canvas. But these coordinates are not correct because of the zoomed canvas.
I tried to correct these (multiply by (zoomHeigh/screenHeight)) but I can’t find a way to retrieve where I must draw on the original/none-zoomed screen
Whenever I try to implement above method the screen jitters on account of zoom effect but does not zoom essentially. I am drawing circle points on canvas and on zooming I want them to scale further apart. I don’t know if I tend to custom draw those circle points based on dimensions of zoomed canvas why is the overall effect a mere jitter ?