Parameters
bitmap Bitmap: The bitmap to draw using the mesh
meshWidth int: The number of columns in the mesh. Nothing is drawn if this is 0
meshHeight int: The number of rows in the mesh. Nothing is drawn if this is 0
verts float: Array of x,y pairs, specifying where the mesh should be drawn. There must be at least (meshWidth+1) * (meshHeight+1) * 2 + vertOffset values in the array
vertOffset int: Number of verts elements to skip before drawing
colors int: May be null. Specifies a color at each vertex, which is interpolated across the cell, and whose values are multiplied by the corresponding bitmap colors. If not null, there must be at least (meshWidth+1) * (meshHeight+1) + colorOffset values in the array.
colorOffset int: Number of color elements to skip before drawing
paint Paint: May be null. The paint used to draw the bitmap
public class MainActivity extends Activity {
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(MainActivity.this, R.drawable.jinta));
}
private class MyView extends View{
//将图片在横向,纵向划分为20格
private final int WIDTH=20,HEIGHT=20;
//包含441个顶点
private final int COUNT=(WIDTH+1)*(HEIGHT+1);
//保存原坐标
private final float[] verts=new float[COUNT*2];
//保存扭曲后坐标,对图片扭曲关键为修改该数组的值
private final float[] orig=new float[COUNT*2];
public MyView(Context context,int DrawableId) {
super(context);
setFocusable(true);
//加载图片资源
bitmap=BitmapFactory.decodeResource(getResources(), DrawableId);
//获取高,宽
float bitmapWidth=bitmap.getWidth(),
bitmapHeight=bitmap.getHeight();
int index=0;
//对原坐标和扭曲后坐标数组进行初始化操作
for(int y=0;y<=HEIGHT;y++){
float fy=bitmapHeight*y/HEIGHT;
for(int x=0;x<=WIDTH;x++){
float fx=bitmapWidth*x/WIDTH;
orig[index*2+0]=verts[index*2+0]=fx;
orig[index*2+1]=verts[index*2+1]=fy;
index+=1;
}
}
//背景色
setBackgroundColor(Color.WHITE);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmapMesh(bitmap,WIDTH,HEIGHT,verts,0,null,0,null);
}
//cx,cy为touch事件发生坐标
private void wrap(float cx,float cy){
for(int i=0;i<COUNT*2;i+=2){
//dx,dy为当前点距离事件发生点的坐标差
float dx=cx-orig[i+0];
float dy=cy-orig[i+1];
float dd=dx*dx+dy*dy;
//d为当前点与事件发生点的距离
float d=(float)Math.sqrt(dd);
//pull为扭曲度,距离越大扭曲程度越小
float pull=80000/((float)(dd*d));
if(pull>=1){
//距离近,直接扭曲至事件发生点
verts[i+0]=cx;
verts[i+1]=cy;
}else{
//距离稍远,向事件发生偏移
verts[i+0]=orig[i+0]+dx*pull;
verts[i+1]=orig[i+1]+dy*pull;
}
}
//通知组件调用OnDraw重绘
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//触摸事件发生时调用扭曲方法
wrap(event.getX(),event.getY());
return true;
}
}
}