zoom jumps around when I remove my finger and put it again ! anybody knows the problem ?
boolean surfaceTouchEvent(MotionEvent event) {
pointNum=event.getPointerCount();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
// User is pressing down another finger.
float x11 = event.getX(0) - event.getX(1);
float y22 = event.getY(0) - event.getY(1);
z4 = sqrt(x11*x11+y22*y22);
break;
case MotionEvent.ACTION_POINTER_UP:
// User is released one of the fingers.
break;
case MotionEvent.ACTION_MOVE:
if (pointNum >= 2 ) {
x1=event.getX(0);
x2=event.getX(1);
y1=event.getY(0);
y2=event.getY(1);
float x = event.getX(0) - event.getX(1);
float y= event.getY(0) - event.getY(1);
float z3 = sqrt(x*x+y*y);
if (pointNum >= 2 ) {
if ( z3 < z4 ) {
zoom = z3/z4;
}
else {
zoom = z3/z4;
}
zoom = constrain(zoom, 0, 100);
}
press1=event.getSize(0);
press2=event.getSize(1);
}
break;
}
return super.surfaceTouchEvent(event);
}
Related
I want to return my image to original position when I zoom out my image and the the image scale is smaller than the first initial image size
#Override
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale = 0;
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN: // first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG"); // write to LogCat
mode = DRAG;
break;
/*case MotionEvent.ACTION_UP: // first finger lifted
case MotionEvent.ACTION_POINTER_UP: // second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE");
break;*/
case MotionEvent.ACTION_UP: // first finger lifted
mode = NONE;
break;
case MotionEvent.ACTION_POINTER_UP:// second finger lifted
/*matrix.set(savedMatrix);*/
/*view.setScaleType(ImageView.ScaleType.CENTER);*/
Log.v("/h/", ""+scale);
mode = ZOOMOUT;
//When release back to position
matrix.set(savedMatrix);
Log.d(TAG, "mode=ZOOMOUT");
break;
case MotionEvent.ACTION_POINTER_DOWN: // first and second finger down
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 5f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG)
{
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix of points
}
else if (mode == ZOOM)
{
// pinch zooming
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 5f)
{
matrix.set(savedMatrix);
scale = newDist / oldDist; // setting the scaling of the
// matrix...if scale > 1 means
// zoom in...if scale < 1 means
// zoom out
if(scale>1) {
//Zoom In
}else if(scale<1) {
//Zoom Out
}
matrix.postScale(scale, scale, mid.x, mid.y);
Log.v("/h/", ""+scale+mode);
}
}
break;
}
view.setImageMatrix(matrix); // display the transformation on screen
return true; // indicate event was handled
}
/*
* --------------------------------------------------------------------------
* Method: spacing Parameters: MotionEvent Returns: float Description:
* checks the spacing between the two fingers on touch
* ----------------------------------------------------
*/
private float spacing(MotionEvent event)
{
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
/*
* --------------------------------------------------------------------------
* Method: midPoint Parameters: PointF object, MotionEvent Returns: void
* Description: calculates the midpoint between the two fingers
* ------------------------------------------------------------
*/
private void midPoint(PointF point, MotionEvent event)
{
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
Set savedMatrix to view.getImageMatrix() on ACTION_DOWN.
Do zoom/drag changes on a separate matrix
On ACTION_UP or ACTION_POINTER_UP set original matrix back to imageview.
view.setImageMatrix(savedMatrix)
I'm having trouble getting my program in Android Studio to properly constrain the joystick I have created. I have two ImageViews placed on top of one another, one being the joystick itself and one being the base of the joystick. Here is the code:
case R.id.analogStick:
switch(me.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
x = me.getRawX();
y = me.getRawY();
System.out.println(x);
System.out.println(y);
dx = x - v.getX();
dy = y - v.getY();
break;
case MotionEvent.ACTION_UP:
v.setX(originX);
v.setY(originY);
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE:
float xx = originX - me.getRawX();
float yy = originY - me.getRawY();
float displacement = (float) Math.sqrt((xx * xx) + (yy * yy));
if (displacement < baseRadius) {
v.setX(me.getRawX() - dx);
v.setY(me.getRawY() - dy);
}
else {
float ratio = (float) baseRadius / displacement;
float constrainedX = originX + (me.getRawX() - originX) * ratio;
float constrainedY = originY + (me.getRawY() - originY) * ratio;
v.setX(constrainedX);
v.setY(constrainedY);
}
break;
}
break;
The main problem here is when calculating the displacement. The value turns out to be too high even when within bounds of the baseRadius, so the program always goes to the else statement, executing the constrained joystick case at all times. I get the base radius by the following formula: baseRadius = baseJoystickImage.getWidth() / 2, with baseJoystickImage being an ImageView variable. I'm not sure what could be going wrong here, any help would be appreciated.
I have an ImageView and i want to zoom/drag on by two fingers and draw on it using one finger , but after scaling ImageView , bitmap coordinates and ImageView coordinates doesn't match , to solve this i provided onTouch like this :
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
final int NONE = 0;
final int DRAW = 1;
final int PINCH = 2;
float x,y;
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
drawStartX = event.getX();
drawStartY = event.getY();
imageMode = DRAW;
break;
case MotionEvent.ACTION_POINTER_DOWN:
//drag
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
oldDistance = (float) Math.sqrt(x * x + y * y);
if (oldDistance > 5f) {
savedMatrix.set(matrix);
x = event.getX(0) + event.getX(1);
y = event.getY(0) + event.getY(1);
mid.set(x / 2, y / 2);
imageMode = PINCH;
}
break;
case MotionEvent.ACTION_UP:
imageMode = NONE;
break;
case MotionEvent.ACTION_POINTER_UP:
imageMode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (imageMode == DRAW) {
float drawEndX = event.getX();
float drawEndY = event.getY();
drawTest(drawStartX/bitmapScale - xTranslate, drawStartY/bitmapScale- yTranslate,drawEndX/bitmapScale - xTranslate,drawEndY/bitmapScale - yTranslate,0);
} else if (imageMode == PINCH) {
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
float newDistance = (float) Math.sqrt(x * x + y * y);
matrix.set(savedMatrix);
if(newDistance > 5f) {
//drag
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
matrix.postTranslate(dx, dy);
//zoom
float scale = (newDistance / oldDistance);
matrix.postScale(scale, scale);
}
//get matrix
float[] mat = new float[9];
matrix.getValues(mat);
bitmapScale = mat[0];
xTranslate = mat[2];
yTranslate = mat[5];
}
break;
}
view.setImageMatrix(matrix);
return true;
}
drawTest is just a void that draws a line.
pic
in before scale picture i drag my finger on imageview and line drawn in exact position , but after scaling i dragged on same position but result is not right
but it's not working properly. how can i fix it ?
I am using following code to drag a View across the screen
tweatBtn.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
float currX,currY;
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN:
{
mPrevX = event.getRawX();
mPrevY = event.getRawY();
btnPrevX = tweatBtn.getX();
btnPrevY = tweatBtn.getY();
break;
}
case MotionEvent.ACTION_MOVE:
{
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth() + 80; // deprecated
int height = display.getHeight(); // deprecated
currX = event.getRawX();
currY = event.getRawY();
if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width)
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
else
{
if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10))
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
});
}
It works fine but sometimes when i lift the Finger it automatically triggers click.How can i improve?
You are returning always false at the end of the code. Which means the touchListener you have set is not handling the touch. Because of if it, View will consider any normal touch as click. What you should do is return True, when the view is dragged, else you should return False
boolean dragged = false;
ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
int minTouchSlop = viewConfiguration.getScaledTouchSlop();
.....
public boolean onTouch(View v, MotionEvent event)
{
float currX,currY;
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN:
{
mPrevX = event.getRawX();
mPrevY = event.getRawY();
btnPrevX = tweatBtn.getX();
btnPrevY = tweatBtn.getY();
dragged = false; // global dragged variable
break;
}
case MotionEvent.ACTION_MOVE:
{
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth() + 80; // deprecated
int height = display.getHeight(); // deprecated
currX = event.getRawX();
currY = event.getRawY();
if(Math.abs(currX-mPrevX) > minTouchSlop || Math.abs(currY-mPrevY) > minTouchSlop)
dragged = true; // differntiate btw drag or click
if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width)
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
else
{
if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10))
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return dragged;
}
I am developing an interactive video installation with touch screen control via an android device. I came up with the following code for panning, zooming and a pan limit so far. But I can't figure out how to limit the zooming (min/max) and how to avoid that the image get out of the boundaries (it should be displayed on the complete screen without any offset).
Thank you for your help!
public boolean onTouchEvent(MotionEvent me) {
switch (me.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
startPoint.set(me.getX(), me.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(me);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(midPoint, me);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float transX = me.getX() - startPoint.x;
float transY = me.getY() - startPoint.y;
matrix.set(savedMatrix);
float[] f = new float[9];
matrix.getValues(f);
float viewWidth = 1317.0f + 1317.0f * ((f[Matrix.MSCALE_X] - 1) / 1.1365f );
float viewWidth2 = 772.0f + 772.0f * ((f[Matrix.MSCALE_X] - 1) / 1.998f);
float viewHeight = 1097.0f + 1097.0f * ((f[Matrix.MSCALE_X] - 1) / 1.463f);
float viewHeight2 = 749.0f + 749.0f * ((f[Matrix.MSCALE_X] - 1) / 2.994f);
if (f[Matrix.MTRANS_X] + transX < -viewWidth){
Log.e("", "left bound");
transX = -f[Matrix.MTRANS_X] -viewWidth;
}
if(f[Matrix.MTRANS_X] + transX > -viewWidth2 ){
transX = -f[Matrix.MTRANS_X] -viewWidth2;
}
if (f[Matrix.MTRANS_Y] + transY > viewHeight){
transY = -f[Matrix.MTRANS_Y] + viewHeight;
}
if(f[Matrix.MTRANS_Y] + transY < viewHeight2){
transY = -f[Matrix.MTRANS_Y] + viewHeight2;
}
matrix.postTranslate(transX, transY);
} else if (mode == ZOOM) {
float newDist = spacing(me);
if (newDist > 10f) {
Log.e("MainActivity", "Correction: " + Float.toString(newDist / newDist));
float transX = me.getX() - startPoint.x;
float transY = me.getY() - startPoint.y;
matrix.set(savedMatrix);
float scale = newDist / oldDist;
float[] f = new float[9];
matrix.getValues(f);
matrix.postScale(scale, scale, -startPoint.x+300.f, -startPoint.y+900.0f);
if (f[Matrix.MSCALE_X] >= 270.0f) {
matrix.postScale((270.0f)/(f[Matrix.MSCALE_X]/scale), (270.0f)/(f[Matrix.MSCALE_Y]*scale), 0f ,0f);
mode = DRAG;
savedMatrix.set(matrix);
midPoint(midPoint, me);
} else if (f[Matrix.MSCALE_X] < 0.29f) {
matrix.postScale((0.29f)/(f[Matrix.MSCALE_X]/scale), (0.29f)/(f[Matrix.MSCALE_Y]*scale), 0f ,0f);
mode = DRAG;
savedMatrix.set(matrix);
midPoint(midPoint, me);
}
}
}
break;
}
// Matrix
try {
socket = new DatagramSocket();
// socket.setBroadcast(true);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String dataString = matrix.toShortString();
Log.e("Activity_Main", dataString);
try {
DatagramPacket packet = new DatagramPacket(dataString.getBytes(), dataString.length(), serverAddr, PORT);
socket.send(packet);
socket.close();
} catch (Exception e) {
}
return true;
}
#SuppressLint("FloatMath")
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}