android酷炫翻页效果+图形分析

来源:互联网 发布:msf漏洞渗通135端口 编辑:程序博客网 时间:2024/06/05 05:55
import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.ColorMatrix;import android.graphics.ColorMatrixColorFilter;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Path.Direction;import android.graphics.PointF;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Region.Op;import android.graphics.drawable.GradientDrawable;import android.view.MotionEvent;import android.view.View;import android.widget.Scroller;public class PageWidget extends View{private static final String TAG = "hmg"; private int mWidth = 1024; private int mHeight = 800; private int mCornerX = 0; // 拖拽点对应的页脚 private int mCornerY = 0; private Path mPath0; private Path mPath1; Bitmap mCurPageBitmap = null; // 当前页 Bitmap mCurPageBackBitmap = null; Bitmap mNextPageBitmap = null; PointF mTouch = new PointF(); // 拖拽点 PointF mBezierStart1 = new PointF(); // 贝塞尔曲线起始点 PointF mBezierControl1 = new PointF(); // 贝塞尔曲线控制点 PointF mBeziervertex1 = new PointF(); // 贝塞尔曲线顶点 PointF mBezierEnd1 = new PointF(); // 贝塞尔曲线结束点 PointF mBezierStart2 = new PointF(); // 另一条贝塞尔曲线起点 PointF mBezierControl2 = new PointF();//贝塞尔曲线的控制点 PointF mBeziervertex2 = new PointF();//贝塞尔曲线的顶点 PointF mBezierEnd2 = new PointF();//贝塞尔曲线的结束点 float mMiddleX; float mMiddleY; float mDegrees; float mTouchToCornerDis; ColorMatrixColorFilter mColorMatrixFilter; Matrix mMatrix; float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f }; boolean mIsRTandLB; // 是否属于右上左下 // for test float mMaxLength = (float) Math.hypot(1024, 800); int[] mBackShadowColors; int[] mFrontShadowColors; GradientDrawable mBackShadowDrawableLR; GradientDrawable mBackShadowDrawableRL; GradientDrawable mFolderShadowDrawableLR; GradientDrawable mFolderShadowDrawableRL; GradientDrawable mFrontShadowDrawableHBT; GradientDrawable mFrontShadowDrawableHTB; GradientDrawable mFrontShadowDrawableVLR; GradientDrawable mFrontShadowDrawableVRL; private Bitmap mBitmap; private Canvas mCanvas; private Paint mBitmapPaint; Paint paint; Paint mPaint; public PageWidget(Context context) {  super(context);  // TODO Auto-generated constructor stub  mPath0 = new Path();  mPath1 = new Path();  createDrawable();  // ---------------------------------------  mBitmap = Bitmap.createBitmap(1024, 800, Bitmap.Config.ARGB_8888);  mCanvas = new Canvas(mBitmap);    mBitmapPaint = new Paint(Paint.DITHER_FLAG);  paint = new Paint();  mPaint = new Paint();  mPaint.setStyle(Paint.Style.FILL);  mCurPageBitmap = BitmapFactory.decodeFile("/mnt/sdcard/media/cn6456724.jpg");   mNextPageBitmap =BitmapFactory.decodeFile("/mnt/sdcard/media/cn6249784.jpg");   ColorMatrix cm = new ColorMatrix();  float array[] = { 0.55f, 0, 0, 0, 80.0f, 0, 0.55f, 0, 0, 80.0f, 0, 0,    0.55f, 0, 80.0f, 0, 0, 0, 0.2f, 0 };  cm.set(array);  mColorMatrixFilter = new ColorMatrixColorFilter(cm);  mMatrix = new Matrix(); }  private void calcCornerXY(float x, float y) {  if (x <= mWidth / 2)   mCornerX = 0;  else   mCornerX = mWidth;  if (y <= mHeight / 2)   mCornerY = 0;  else   mCornerY = mHeight;  if ((mCornerX == 0 && mCornerY == mHeight)    || (mCornerX == mWidth && mCornerY == 0))   mIsRTandLB = true;  else   mIsRTandLB = false; } @Override public boolean onTouchEvent(MotionEvent event) {  // TODO Auto-generated method stub  if (event.getAction() == MotionEvent.ACTION_MOVE) {   mCanvas.drawColor(0xFFAAAAAA);   mTouch.x = event.getX();   mTouch.y = event.getY();   this.postInvalidate();  }  if (event.getAction() == MotionEvent.ACTION_DOWN) {   mCanvas.drawColor(0xFFAAAAAA);   mTouch.x = event.getX();   mTouch.y = event.getY();   calcCornerXY(mTouch.x, mTouch.y);   this.postInvalidate();  }  if (event.getAction() == MotionEvent.ACTION_UP) {   mCanvas.drawColor(0xFFAAAAAA);   mTouch.x = mCornerX;   mTouch.y = mCornerY;   this.postInvalidate();  }  // return super.onTouchEvent(event);  return true; }  public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {  PointF CrossP = new PointF();  // 二元函数通式: y=ax+b  float a1 = (P2.y - P1.y) / (P2.x - P1.x);  float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x);  float a2 = (P4.y - P3.y) / (P4.x - P3.x);  float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x);  CrossP.x = (b2 - b1) / (a1 - a2);  CrossP.y = a1 * CrossP.x + b1;  return CrossP; } private void calcPoints() {    mMiddleX = (mTouch.x + mCornerX) / 2;  mMiddleY = (mTouch.y + mCornerY) / 2;    System.out.println(mTouch.x+"----------------x");  System.out.println(mTouch.y+"----------------y");  System.out.println(mCornerX+"----------------cornerX");  System.out.println(mCornerY+"----------------cornerY");  //贝塞尔曲线的控制点的横坐标  mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY)    * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);    mBezierControl1.y = mCornerY;    System.out.println(mBezierControl1.x+"----------------mBezierControl1X");  System.out.println(mBezierControl1.y+"----------------mBezierControl1Y");  mBezierControl2.x = mCornerX;  mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)    * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);  System.out.println("mTouchX  " + mTouch.x + "  mTouchY  " + mTouch.y);  System.out.println("mBezierControl1.x  " + mBezierControl1.x    + "  mBezierControl1.y  " + mBezierControl1.y);  System.out.println("mBezierControl2.x  " + mBezierControl2.x    + "  mBezierControl2.y  " + mBezierControl2.y);  mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x)    / 2;  mBezierStart1.y = mCornerY;           // 当mBezierStart1.x < 0或者mBezierStart1.x > 480时  // 如果继续翻页,会出现BUG故在此限制  if (mBezierStart1.x < 0 || mBezierStart1.x > 1024) {   System.out.println("page move");   if (mBezierStart1.x < 0)            mBezierStart1.x = mWidth - mBezierStart1.x;   float f1 = Math.abs(mCornerX - mTouch.x);   float f2 = mWidth * f1 / mBezierStart1.x;   mTouch.x = Math.abs(mCornerX - f2);   float f3 = Math.abs(mCornerX - mTouch.x)     * Math.abs(mCornerY - mTouch.y) / f1;   mTouch.y = Math.abs(mCornerY - f3);   mMiddleX = (mTouch.x + mCornerX) / 2;   mMiddleY = (mTouch.y + mCornerY) / 2;   mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY)     * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);   mBezierControl1.y = mCornerY;   mBezierControl2.x = mCornerX;   mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)     * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);   System.out.println("mTouchX --> " + mTouch.x + "  mTouchY-->  "     + mTouch.y);   System.out.println("mBezierControl1.x--  " + mBezierControl1.x     + "  mBezierControl1.y -- " + mBezierControl1.y);   System.out.println("mBezierControl2.x -- " + mBezierControl2.x     + "  mBezierControl2.y -- " + mBezierControl2.y);   mBezierStart1.x = mBezierControl1.x     - (mCornerX - mBezierControl1.x) / 2;  }  mBezierStart2.x = mCornerX;  mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y)    / 2;  mTouchToCornerDis = (float) Math.hypot((mTouch.x - mCornerX),    (mTouch.y - mCornerY));  //两条贝塞尔曲线的终点的坐标值  mBezierEnd1 = getCross(mTouch, mBezierControl1, mBezierStart1,    mBezierStart2);  mBezierEnd2 = getCross(mTouch, mBezierControl2, mBezierStart1,    mBezierStart2);  System.out.println("mBezierEnd1.x  " + mBezierEnd1.x + "  mBezierEnd1.y  "    + mBezierEnd1.y);  System.out.println("mBezierEnd2.x  " + mBezierEnd2.x + "  mBezierEnd2.y  "    + mBezierEnd2.y);    mBeziervertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4;  mBeziervertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4;  mBeziervertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4;  mBeziervertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4; } private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap, Path path) {  mPath0.reset();  mPath0.moveTo(mBezierStart1.x, mBezierStart1.y);  mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x,    mBezierEnd1.y);  mPath0.lineTo(mTouch.x, mTouch.y);  mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y);  mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x,    mBezierStart2.y);  mPath0.lineTo(mCornerX, mCornerY);  mPath0.close();  canvas.save();  canvas.clipPath(path, Op.XOR);  canvas.drawBitmap(bitmap, 0, 0, null);  canvas.restore(); } private void drawNextPageAreaAndShadow(Canvas canvas, Bitmap bitmap) {  mPath1.reset();  mPath1.moveTo(mBezierStart1.x, mBezierStart1.y);  mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);  mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y);  mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);  mPath1.lineTo(mCornerX, mCornerY);  mPath1.close();  mDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl1.x    - mCornerX, mBezierControl2.y - mCornerY));  int leftx;  int rightx;  GradientDrawable mBackShadowDrawable;  if (mIsRTandLB) {   leftx = (int) (mBezierStart1.x);   rightx = (int) (mBezierStart1.x + mTouchToCornerDis / 4);   mBackShadowDrawable = mBackShadowDrawableLR;  } else {   leftx = (int) (mBezierStart1.x - mTouchToCornerDis / 4);   rightx = (int) mBezierStart1.x;   mBackShadowDrawable = mBackShadowDrawableRL;  }  canvas.save();  canvas.clipPath(mPath0);  canvas.clipPath(mPath1, Op.INTERSECT);  canvas.drawBitmap(bitmap, 0, 0, null);  canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);  mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.y, rightx,    (int) (mMaxLength + mBezierStart1.y));  mBackShadowDrawable.draw(canvas);  canvas.restore(); } public void setBitmaps(Bitmap bm1, Bitmap bm2, Bitmap bm3) {  mCurPageBitmap = bm1;  mCurPageBackBitmap = bm2;  mNextPageBitmap = bm3; } @Override protected void onDraw(Canvas canvas) {  System.out.println("onDraw");  canvas.drawColor(0xFFAAAAAA);  calcPoints();  drawCurrentPageArea(mCanvas, mCurPageBitmap, mPath0);  drawNextPageAreaAndShadow(mCanvas, mNextPageBitmap);  drawCurrentPageShadow(mCanvas);  drawCurrentBackArea(mCanvas, mCurPageBitmap);  canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); }  private void createDrawable() {  int[] color = { 0x333333, 0xb0333333 };  mFolderShadowDrawableRL = new GradientDrawable(    GradientDrawable.Orientation.RIGHT_LEFT, color);  mFolderShadowDrawableRL    .setGradientType(GradientDrawable.LINEAR_GRADIENT);  mFolderShadowDrawableLR = new GradientDrawable(    GradientDrawable.Orientation.LEFT_RIGHT, color);  mFolderShadowDrawableLR    .setGradientType(GradientDrawable.LINEAR_GRADIENT);  mBackShadowColors = new int[] { 0xff111111, 0x111111 };  mBackShadowDrawableRL = new GradientDrawable(    GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors);  mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);  mBackShadowDrawableLR = new GradientDrawable(    GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);  mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);  mFrontShadowColors = new int[] { 0x80111111, 0x111111 };  mFrontShadowDrawableVLR = new GradientDrawable(    GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors);  mFrontShadowDrawableVLR    .setGradientType(GradientDrawable.LINEAR_GRADIENT);  mFrontShadowDrawableVRL = new GradientDrawable(    GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors);  mFrontShadowDrawableVRL    .setGradientType(GradientDrawable.LINEAR_GRADIENT);  mFrontShadowDrawableHTB = new GradientDrawable(    GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors);  mFrontShadowDrawableHTB    .setGradientType(GradientDrawable.LINEAR_GRADIENT);  mFrontShadowDrawableHBT = new GradientDrawable(    GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors);    mFrontShadowDrawableHBT    .setGradientType(GradientDrawable.LINEAR_GRADIENT);      }  public void drawCurrentPageShadow(Canvas canvas) {  double degree;  if (mIsRTandLB) {   degree = Math.PI     / 4     - Math.atan2(mBezierControl1.y - mTouch.y, mTouch.x       - mBezierControl1.x);  } else {   degree = Math.PI     / 4     - Math.atan2(mTouch.y - mBezierControl1.y, mTouch.x       - mBezierControl1.x);  }  //翻起页阴影顶点与touch点的距离  double d1 = (float) 25 * 1.414 * Math.cos(degree);  double d2 = (float) 25 * 1.414 * Math.sin(degree);  float x = (float) (mTouch.x + d1);  float y;  if (mIsRTandLB) {   y = (float) (mTouch.y + d2);    } else {   y = (float) (mTouch.y - d2);  }  mPath1.reset();  mPath1.moveTo(x, y);  mPath1.lineTo(mTouch.x, mTouch.y);  mPath1.lineTo(mBezierControl1.x, mBezierControl1.y);  mPath1.lineTo(mBezierStart1.x, mBezierStart1.y);  mPath1.close();  float rotateDegrees;  canvas.save();  canvas.clipPath(mPath0, Op.XOR);  canvas.clipPath(mPath1, Op.INTERSECT);  int leftx;  int rightx;  GradientDrawable mCurrentPageShadow;  if (mIsRTandLB) {   leftx = (int) (mBezierControl1.x);   rightx = (int) mBezierControl1.x + 25;   mCurrentPageShadow = mFrontShadowDrawableVLR;  } else {   leftx = (int) (mBezierControl1.x - 25);   rightx = (int) mBezierControl1.x + 1;   mCurrentPageShadow = mFrontShadowDrawableVRL;  }  rotateDegrees = (float) Math.toDegrees(Math.atan2(mTouch.x    - mBezierControl1.x, mBezierControl1.y - mTouch.y));  canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y);  mCurrentPageShadow.setBounds(leftx,    (int) (mBezierControl1.y - mMaxLength), rightx,    (int) (mBezierControl1.y));  mCurrentPageShadow.draw(canvas);  canvas.restore();  mPath1.reset();  mPath1.moveTo(x, y);  mPath1.lineTo(mTouch.x, mTouch.y);  mPath1.lineTo(mBezierControl2.x, mBezierControl2.y);  mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);  mPath1.close();  canvas.save();  canvas.clipPath(mPath0, Op.XOR);  canvas.clipPath(mPath1, Op.INTERSECT);  if (mIsRTandLB) {   leftx = (int) (mBezierControl2.y);   rightx = (int) (mBezierControl2.y + 25);   mCurrentPageShadow = mFrontShadowDrawableHTB;  } else {   leftx = (int) (mBezierControl2.y - 25);   rightx = (int) (mBezierControl2.y + 1);   mCurrentPageShadow = mFrontShadowDrawableHBT;  }  rotateDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl2.y    - mTouch.y, mBezierControl2.x - mTouch.x));  canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y);  float temp;  if (mBezierControl2.y < 0)   temp = mBezierControl2.y - 800;  else   temp = mBezierControl2.y;  int hmg = (int) Math.hypot(mBezierControl2.x, temp);  if (hmg > mMaxLength)   mCurrentPageShadow     .setBounds((int) (mBezierControl2.x - 25) - hmg, leftx,       (int) (mBezierControl2.x + mMaxLength) - hmg,       rightx);  else   mCurrentPageShadow.setBounds(     (int) (mBezierControl2.x - mMaxLength), leftx,     (int) (mBezierControl2.x), rightx);  System.out.println("mBezierControl2.x   " + mBezierControl2.x    + "  mBezierControl2.y  " + mBezierControl2.y);  mCurrentPageShadow.draw(canvas);  canvas.restore(); }  private void drawCurrentBackArea(Canvas canvas, Bitmap bitmap) {  int i = (int) (mBezierStart1.x + mBezierControl1.x) / 2;  float f1 = Math.abs(i - mBezierControl1.x);  int i1 = (int) (mBezierStart2.y + mBezierControl2.y) / 2;  float f2 = Math.abs(i1 - mBezierControl2.y);  float f3 = Math.min(f1, f2);  mPath1.reset();  mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);  mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);  mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);  mPath1.lineTo(mTouch.x, mTouch.y);  mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);  mPath1.close();  GradientDrawable mFolderShadowDrawable;  int left;  int right;  if (mIsRTandLB) {   left = (int) (mBezierStart1.x - 1);   right = (int) (mBezierStart1.x + f3 + 1);   mFolderShadowDrawable = mFolderShadowDrawableLR;  } else {   left= (int) (mBezierStart1.x - f3 - 1);   right= (int) (mBezierStart1.x + 1);   mFolderShadowDrawable = mFolderShadowDrawableRL;  }  canvas.save();  canvas.clipPath(mPath0);  canvas.clipPath(mPath1, Op.INTERSECT);  mPaint.setColorFilter(mColorMatrixFilter);  float dis = (float) Math.hypot(mCornerX - mBezierControl1.x,    mBezierControl2.y - mCornerY);  float f8 = (mCornerX - mBezierControl1.x) / dis;  float f9 = (mBezierControl2.y - mCornerY) / dis;  mMatrixArray[0] = 1 - 2 * f9 * f9;  mMatrixArray[1] = 2 * f8 * f9;  mMatrixArray[3] = mMatrixArray[1];  mMatrixArray[4] = 1 - 2 * f8 * f8;  mMatrix.reset();  mMatrix.setValues(mMatrixArray);  mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y);  mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);  canvas.drawBitmap(bitmap, mMatrix, mPaint);  // canvas.drawBitmap(bitmap, mMatrix, null);  mPaint.setColorFilter(null);  canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);  mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right,    (int) (mBezierStart1.y + mMaxLength));  mFolderShadowDrawable.draw(canvas);  canvas.restore(); }        }
//Activitypublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);  requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(  WindowManager.LayoutParams.FLAG_FULLSCREEN,  WindowManager.LayoutParams.FLAG_FULLSCREEN);     setContentView(new PageWidget(this));         }