Skip to content

Instantly share code, notes, and snippets.

@jopedroliveira
Created November 5, 2016 10:43
Show Gist options
  • Save jopedroliveira/482975d15457ee645e11fbb30e0b24c3 to your computer and use it in GitHub Desktop.
Save jopedroliveira/482975d15457ee645e11fbb30e0b24c3 to your computer and use it in GitHub Desktop.
package adefault.com.pointt;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.media.Image;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.util.ArrayList;
import java.util.Random;
/**
* Created by PedroOliveira on 19/10/16.
*/
class MyView extends View {
private static final String TAG = "Point";
public static Matrix matrix = new Matrix();
public static Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
private static final float MIN_ZOOM = 1f;
private static final float MAX_ZOOM = 4f;
int mode = NONE;
float scale = 1L;
RelativeLayout lt = null;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
int width, height;
ImageView view = null;
Context mContext;
public MyView(Context context, ImageView img, RelativeLayout lt) {
super(context);
this.view = img;
this.lt = lt;
mContext = context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
LayoutInflater inflater = LayoutInflater.from(mContext);
width = view.getWidth();
height = view.getHeight();
float nx = 0L;
float ny = 0L;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: // CLICAR APENAS >> criar um ponto (objeto)
if (!MainActivity.getMode()) {
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
} else {
savedMatrix.set(matrix);
mode = NONE;
Point po = new Point();
po.x = (int) event.getX() - 15; //ofset para o centro da imagem coincidir com o local do toque
po.y = (int) event.getY() - 15; //ofset para o centro da imagem coincidir com o local do toque
float[] val = new float[9];
matrix.getValues(val);
po.transX = val[Matrix.MTRANS_X];
po.transY = val[Matrix.MTRANS_Y];
po.scaleX = val[Matrix.MSCALE_X];
po.scaleY = val[Matrix.MSCALE_Y];
Log.e(TAG, "Tx_point_creation: " + po.transX + " Ty_point_creation: " + po.transY);
MainActivity.addE(po);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30, 30);
params.leftMargin = po.x;
params.topMargin = po.y;
View child = inflater.inflate(R.layout.i, null);
child.setLayoutParams(params);
child.setOnTouchListener(new ChoiceTouchListener(po));
// atribuir id ao ponto. idealmente, funcionará com o nome do prórpio ponto da variavel
Random r = new Random();
int id = r.nextInt(10000);
child.setId(id);
po.id = id;
po.child = child;
add(child);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG && !MainActivity.getMode()) {
matrix.set(savedMatrix);
nx = (float) ((event.getX() - start.x) * 0.15);
ny = (float) ((event.getY() - start.y) * 0.15);
matrix.postTranslate(nx, ny);
break;
} else if (mode == ZOOM && !MainActivity.getMode()) {
float newDist = spacing(event);
if (newDist > 5f) {
//savedMatrix.set(matrix);
if (newDist / oldDist > 1) {
scale = (float) 1.03;
} else {
scale = (float) ((float) 1 / 1.03);
}
Log.e(TAG, "scale: " + scale);
float[] valuesTransformation = new float[9];
matrix.getValues(valuesTransformation);
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
matrix = limitZoom(matrix);
matrix = limitDrag(matrix);
savedMatrix.set(matrix);
view.setImageMatrix(savedMatrix);
ArrayList<Point> pointlist = (ArrayList<Point>) MainActivity.getPointList();
if (!pointlist.isEmpty() && !MainActivity.getMode()) {
for (Point p : pointlist) {
float[] valuesTransformation = new float[9];
matrix.getValues(valuesTransformation);
float transformTX = valuesTransformation[Matrix.MTRANS_X];
float transformTY = valuesTransformation[Matrix.MTRANS_Y];
float transformSX = valuesTransformation[Matrix.MSCALE_X];
float transformSY = valuesTransformation[Matrix.MSCALE_Y];
float tx = -p.transX + transformTX;
float ty = -p.transY + transformTY;
Log.e(TAG, "Original TX: " + p.transX + " Original TY: " + p.transY);
Log.e(TAG, "Transformation TX: " + transformTX + " Transformation TY: " + transformTY);
Log.e(TAG, "TX: " + tx + " TY: " + ty);
p.child.setTranslationX(tx);
p.child.setTranslationY(ty);
}
}
//invalidate();
return true;
}
/**
* Determine the space between the first two fingers
*/
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));
}
/**
* Calculate the mid point of the first 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);
}
private Matrix limitZoom(Matrix m) {
float[] values = new float[9];
m.getValues(values);
float scaleX = values[Matrix.MSCALE_X];
float scaleY = values[Matrix.MSCALE_Y];
if (scaleX > MAX_ZOOM) {
scaleX = MAX_ZOOM;
} else if (scaleX < MIN_ZOOM) {
scaleX = MIN_ZOOM;
}
if (scaleY > MAX_ZOOM) {
scaleY = MAX_ZOOM;
} else if (scaleY < MIN_ZOOM) {
scaleY = MIN_ZOOM;
}
values[Matrix.MSCALE_X] = scaleX;
values[Matrix.MSCALE_Y] = scaleY;
m.setValues(values);
return m;
}
private Matrix limitDrag(Matrix m) {
float[] values = new float[9];
m.getValues(values);
float transX = values[Matrix.MTRANS_X];
float transY = values[Matrix.MTRANS_Y];
float scaleX = values[Matrix.MSCALE_X];
float scaleY = values[Matrix.MSCALE_Y];
//--- limit moving to left ---
float minX = (-width + 0) * (scaleX - 1);
float minY = (-height + 0) * (scaleY - 1);
//--- limit moving to right ---
float maxX = minX + width * (scaleX - 1);
float maxY = minY + height * (scaleY - 1);
if (transX > maxX) {
transX = maxX;
}
if (transX < minX) {
transX = minX;
}
if (transY > maxY) {
transY = maxY;
}
if (transY < minY) {
transY = minY;
}
values[Matrix.MTRANS_X] = transX;
values[Matrix.MTRANS_Y] = transY;
m.setValues(values);
return m;
}
private void add(View child) {
lt.addView(child);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment