Now that we've identified the different states we are in, we can go on and start to implement the dragging/panning functionality. Panning essentially equates to a translation operation on the canvas. By translating the canvas, we control what part of the zoomed-in canvas we display on the device screen. So what information do we need to translate? Well, think about what we expect to see when we pan. We place our finger on the screen and then we move it by a certain amount in a certain direction. We essentially expect the image to move by that same amount, in that same direction as well. So the direction and magnitude that we need to translate the image by, can be gathered from the coordinate where we first pressed the screen, through each point until we take our finger off the screen. Getting all this information is pretty easy. We can get the X and Y coordinate of the finger using event.getX()
and event.getY()
. So all we need to do is get the X and Y coordinate when we first press our finger on the screen, and translate the image as we move our finger across the screen, by getting the finger's X and Y coordinates each time the finger moves. We can do that like this:
public class ZoomView extends View {
...
...
//These two variables keep track of the X and Y coordinate of the finger when it first
//touches the screen
private float startX = 0f;
private float startY = 0f;
//These two variables keep track of the amount we need to translate the canvas along the X
//and the Y coordinate
private float translateX = 0f;
private float translateY = 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. So these variables now
//hold the X and Y coordinate of the finger as it first touches the screen.
startX = event.getX();
startY = event.getY();
...
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;
...
...
}
...
...
}
}
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 ?