还有许多问题,关键是Gradient的修改。先保存下现有成果。
Page.h
#pragma once #include "SkPreConfig.h" #include "SkCanvas.h" #include "SkRect.h" #include "SkStream.h" #include "SkPoint.h" #include "SkGradientShader.h" //SkGradientShader渐变色绘制(用于阴影) #include "SkPath.h" //路径,用于路径裁剪 #include "SkColorMatrix.h" #include "SkColorMatrixFilter.h" #include "SkImageDecoder.h" #include "utils/skcamera.h" //#include "skMath.h" class CPage { public: CPage(void); ~CPage(void); void CreateShader(); void CalcCornerXY(float x,float y); BOOL DoTouchEvent(); SkPoint GetCross(SkPoint p1,SkPoint p2,SkPoint p3,SkPoint p4); void CalcPoints(); //void DrawCurrentPageArea(SkCanvas *canvas, SkBitmap *bitmap, SkPath *path); void DrawCurrentPageArea(SkCanvas *canvas, SkBitmap *bitmap); void DrawNextPageAreaAndShadow(SkCanvas *canvas, SkBitmap *bitmap); void SetBitmaps(SkBitmap *bm1, SkBitmap *bm2); void SetScreen(int w, int h); void DrawCurrentPageShadow(SkCanvas *canvas); void DrawCurrentBackArea(SkCanvas *canvas, SkBitmap *bitmap); void StartAnimation(int delayMillis); void AbortAnimation(); BOOL CanDragOver(); BOOL DragToRight(); //void DrawPage(SkCanvas *canvas); void DrawPage(SkCanvas *canvas,SkPoint touch); BOOL LButtonDown(SkCanvas *canvas,SkPoint pt); BOOL MouseMove(SkCanvas *canvas,SkPoint pt); BOOL LButtonUp(SkCanvas *canvas,SkPoint pt); int mCornerX ; // 拖拽点对应的页脚 int mCornerY ; private: int mWidth; //屏幕宽度 800 int mHeight; //屏幕高度 480 SkPath mPath0; //裁剪路径 SkPath mPath1; SkBitmap *mCurPageBitmap ; // 当前页,由使用者传入 SkBitmap *mNextPageBitmap ; SkPoint mTouch; // 拖拽点 SkPoint mBezierStart1; // 贝塞尔曲线起始点 SkPoint mBezierControl1 ; // 贝塞尔曲线控制点 SkPoint mBeziervertex1 ; // 贝塞尔曲线顶点 SkPoint mBezierEnd1 ; // 贝塞尔曲线结束点 SkPoint mBezierStart2 ; // 另一条贝塞尔曲线 SkPoint mBezierControl2 ; SkPoint mBeziervertex2 ; SkPoint mBezierEnd2 ; float mMiddleX; float mMiddleY; float mDegrees; float mTouchToCornerDis; SkColorMatrixFilter *mpColorMatrixFilter; SkMatrix mMatrix; //float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f }; float mMatrixArray[9] ; boolean mIsRTandLB; // 是否属于右上左下 //float mMaxLength = (float) Math.hypot(mWidth, mHeight);计算直角三角形协边 float mMaxLength ;//屏幕对角线 //int[] mBackShadowColors; //int[] mFrontShadowColors; //int * mBackShadowColors; //int * mFrontShadowColors; SkShader *mBackShadowDrawableLR; SkShader *mBackShadowDrawableRL; SkShader *mFolderShadowDrawableLR; SkShader *mFolderShadowDrawableRL; SkShader *mFrontShadowDrawableHBT; SkShader *mFrontShadowDrawableHTB; SkShader *mFrontShadowDrawableVLR; SkShader *mFrontShadowDrawableVRL; SkPaint mPaint; HWND mHwnd; };
Page.cpp
#include "StdAfx.h" #include "Page.h" #include "math.h" #define PI (3.141592653) CPage::CPage(void) { mWidth = 800; mHeight = 480; mCornerX = 0; mCornerY = 0; mCurPageBitmap = NULL; mNextPageBitmap = NULL; mMaxLength = _hypot(mWidth,mHeight); CreateShader(); mPaint.setStyle(SkPaint::Style::kFill_Style); //SkColorMatrix cm; float farray[] = {0.55f,0, 0, 0, 80.0f,// 0-4 0, 0.55f,0, 0, 80.0f,// 5-9 0, 0, 0.55f,0, 80.0f,//10-14 0, 0, 0, 0.2f, 0}; //15-19 //原来用数组farray初始化ColorMatrix,再用 //ColorMatrix初始化ColorMatrixColorFilter, //这里直接用数组farray初始化SkColorMatrixFilter //ColorMatrix是5*4矩阵?分别代表RGBA的Scale? mpColorMatrixFilter =new SkColorMatrixFilter(farray); mTouch.fX = 0.01f; mTouch.fY = 0.01f; //不让x,y为0,否则在点计算时会有问题 for (int i=0;i<9;i++) { mMatrixArray[i] = 0; } mMatrixArray[8] = 1.0f; } CPage::~CPage(void) { } //创建阴影的GradientDrawable void CPage::CreateShader() { SkPoint pt[2]; pt[0].set(0,0); pt[1].set(50,50); SkColor color[] = {0x111111 ,0xb0333333}; mFolderShadowDrawableRL = SkGradientShader::CreateLinear(pt,color,NULL,2,SkShader::TileMode::kClamp_TileMode); //mFolderShadowDrawableLR ; //int backShadowColors[] ={ 0xff111111, 0x111111 }; //mBackShadowDrawableRL ; //mBackShadowDrawableLR ; //int frontShadowColors[] ={ 0x80111111, 0x111111 }; //mFrontShadowDrawableVLR ; //mFrontShadowDrawableVRL ; //mFrontShadowDrawableHTB ; //mFrontShadowDrawableHBT ; } // 计算拖拽点对应的拖拽脚 void CPage::CalcCornerXY(float x,float y) { if (x<=mWidth/2) mCornerX = 0; else mCornerX =mWidth; if(y <=mHeight/2) mCornerY =0; else mCornerY =mHeight; if ((0 == mCornerX && mCornerY == mHeight)//左下角 ||(mCornerX == mWidth && 0 == mCornerY)) //右上 mIsRTandLB = TRUE; else mIsRTandLB = FALSE; } BOOL CPage::DoTouchEvent() { //可以只处理 mousemove/lbuttonup? //LBUTTONDUP中判断是否翻页 return TRUE; } // SkPoint CPage::GetCross(SkPoint p1,SkPoint p2,SkPoint p3,SkPoint p4) { SkPoint CrossP ; float a1 = (p2.fY - p1.fY)/(p2.fX - p1.fX); float b1 = ((p1.fX * p2.fY) - p2.fX*p1.fY)/(p1.fX - p2.fX); float a2 = (p4.fY-p3.fY)/(p4.fX-p3.fX); float b2 = ((p3.fX*p4.fY)-(p4.fX*p3.fY))/(p3.fX-p4.fX); CrossP.fX = (b2-b1)/(a1-a2); CrossP.fY =a1*CrossP.fX +b1; return CrossP; } void CPage::CalcPoints() { mMiddleX = (mTouch.fX + mCornerX)/2; mMiddleY = (mTouch.fY + mCornerY)/2; mBezierControl1.fX = mMiddleX -(mCornerY -mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX); mBezierControl1.fY = mCornerY; mBezierControl2.fX = mCornerX; mBezierControl2.fY = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY); mBezierStart1.fX = mBezierControl1.fX - (mCornerX - mBezierControl1.fX)/ 2; mBezierStart1.fY = mCornerY; // 当mBezierStart1.x < 0或者mBezierStart1.x > 480时 //800 // 如果继续翻页,会出现BUG故在此限制 if (mTouch.fX > 0 && mTouch.fX < mWidth) { if (mBezierStart1.fX < 0 || mBezierStart1.fX > mWidth) { if (mBezierStart1.fX < 0) mBezierStart1.fX = mWidth - mBezierStart1.fX; float f1 = abs(mCornerX - mTouch.fX); float f2 = mWidth * f1 / mBezierStart1.fX; mTouch.fX = abs(mCornerX - f2); float f3 = abs(mCornerX - mTouch.fX) * abs(mCornerY - mTouch.fY) / f1; mTouch.fY = abs(mCornerY - f3); mMiddleX = (mTouch.fX + mCornerX) / 2; mMiddleY = (mTouch.fY + mCornerY) / 2; mBezierControl1.fX = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX); mBezierControl1.fY = mCornerY; mBezierControl2.fX = mCornerX; mBezierControl2.fY = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY); // Log.i("hmg", "mTouchX --> " + mTouch.x + " mTouchY--> " // + mTouch.y); // Log.i("hmg", "mBezierControl1.x-- " + mBezierControl1.x // + " mBezierControl1.y -- " + mBezierControl1.y); // Log.i("hmg", "mBezierControl2.x -- " + mBezierControl2.x // + " mBezierControl2.y -- " + mBezierControl2.y); mBezierStart1.fX = mBezierControl1.fX - (mCornerX - mBezierControl1.fX) / 2; } } mBezierStart2.fX = mCornerX; mBezierStart2.fY = mBezierControl2.fY - (mCornerY - mBezierControl2.fY) / 2; mTouchToCornerDis = (float)_hypot((mTouch.fX - mCornerX),(mTouch.fY - mCornerY)); mBezierEnd1 = GetCross(mTouch, mBezierControl1, mBezierStart1,mBezierStart2); mBezierEnd2 = GetCross(mTouch, mBezierControl2, mBezierStart1,mBezierStart2); // Log.i("hmg", "mBezierEnd1.x " + mBezierEnd1.x + " mBezierEnd1.y " // + mBezierEnd1.y); // Log.i("hmg", "mBezierEnd2.x " + mBezierEnd2.x + " mBezierEnd2.y " // + mBezierEnd2.y); /* * mBeziervertex1.x 推导 * ((mBezierStart1.x+mBezierEnd1.x)/2+mBezierControl1.x)/2 化简等价于 * (mBezierStart1.x+ 2*mBezierControl1.x+mBezierEnd1.x) / 4 */ mBeziervertex1.fX = (mBezierStart1.fX + 2 * mBezierControl1.fX + mBezierEnd1.fX) / 4; mBeziervertex1.fY = (2 * mBezierControl1.fY + mBezierStart1.fY + mBezierEnd1.fY) / 4; mBeziervertex2.fX = (mBezierStart2.fX + 2 * mBezierControl2.fX + mBezierEnd2.fX) / 4; mBeziervertex2.fY = (2 * mBezierControl2.fY + mBezierStart2.fY + mBezierEnd2.fY) / 4; } //void CPage::DrawCurrentPageArea(SkCanvas *canvas, SkBitmap *bitmap, SkPath *path) void CPage::DrawCurrentPageArea(SkCanvas *canvas, SkBitmap *bitmap) { mPath0.reset(); mPath0.moveTo(mBezierStart1.fX, mBezierStart1.fY); mPath0.quadTo(mBezierControl1.fX, mBezierControl1.fY, mBezierEnd1.fX,mBezierEnd1.fY); mPath0.lineTo(mTouch.fX, mTouch.fY); mPath0.lineTo(mBezierEnd2.fX, mBezierEnd2.fY); mPath0.quadTo(mBezierControl2.fX, mBezierControl2.fY, mBezierStart2.fX,mBezierStart2.fY); mPath0.lineTo(mCornerX, mCornerY); mPath0.close(); canvas->save(); canvas->clipPath(mPath0, SkRegion::Op::kXOR_Op); SkPaint paint; paint.setAntiAlias(true); //设置为无锯齿 canvas->drawBitmap(*bitmap, 0, 0, &paint); canvas->restore(); } void CPage::DrawNextPageAreaAndShadow(SkCanvas *canvas, SkBitmap *bitmap) { mPath1.reset(); mPath1.moveTo(mBezierStart1.fX, mBezierStart1.fY); mPath1.lineTo(mBeziervertex1.fX, mBeziervertex1.fY); mPath1.lineTo(mBeziervertex2.fX, mBeziervertex2.fY); mPath1.lineTo(mBezierStart2.fX, mBezierStart2.fY); mPath1.lineTo(mCornerX, mCornerY); mPath1.close(); mDegrees = (float)(atan2(mBezierControl1.fX - mCornerX, mBezierControl2.fY - mCornerY))*180/PI; int leftx; int rightx; SkShader *mBackShadowDrawable; if (mIsRTandLB) { leftx = (int) (mBezierStart1.fX); rightx = (int) (mBezierStart1.fX + mTouchToCornerDis / 4); mBackShadowDrawable = mBackShadowDrawableLR; //从左到又显示阴影 } else { leftx = (int) (mBezierStart1.fX - mTouchToCornerDis / 4); rightx = (int) mBezierStart1.fX; mBackShadowDrawable = mBackShadowDrawableRL; //从右到左显示阴影 } mBackShadowDrawable = mFolderShadowDrawableRL; canvas->save(); canvas->clipPath(mPath0); canvas->clipPath(mPath1, SkRegion::Op::kIntersect_Op); canvas->drawBitmap(*bitmap, 0, 0, NULL); canvas->translate(mBezierStart1.fX, mBezierStart1.fY); canvas->rotate(mDegrees); canvas->translate(-mBezierStart1.fX, -mBezierStart1.fY); //mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.fY, rightx,(int)(mMaxLength + mBezierStart1.fY)); //mBackShadowDrawable.draw(canvas); // Skia没有实现? SkPaint paint; paint.setAntiAlias(true); //设置为无锯齿 paint.setShader(mBackShadowDrawable); canvas->drawRectCoords(leftx, (int) mBezierStart1.fY, rightx,(int)(mMaxLength + mBezierStart1.fY),paint); canvas->restore(); } void CPage::SetBitmaps(SkBitmap *bm1, SkBitmap *bm2) { mCurPageBitmap = bm1; mNextPageBitmap = bm2; } void CPage::SetScreen(int w, int h) { mWidth = w; mHeight = h; } //@Override //protected void onDraw(Canvas canvas) //{ // canvas.drawColor(0xFFAAAAAA); // calcPoints(); // drawCurrentPageArea(canvas, mCurPageBitmap, mPath0); 当前页区域 // drawNextPageAreaAndShadow(canvas, mNextPageBitmap); 下一页区域和阴影 // drawCurrentPageShadow(canvas); 当前页阴影 // drawCurrentBackArea(canvas, mCurPageBitmap); 当前页背影 //} //在java中computeScroll函数中改变mTouch,这里作为参数 void CPage::DrawPage(SkCanvas *canvas,SkPoint touch) { canvas->drawColor(0xFFAAAAAA); mTouch = touch; //CalcCornerXY(mTouch.fX,mTouch.fY);//放在调用处,一次移动只能调用一次 CalcPoints(); DrawCurrentPageArea(canvas,mCurPageBitmap); DrawNextPageAreaAndShadow(canvas,mNextPageBitmap); //DrawCurrentPageShadow(canvas); //DrawCurrentBackArea(canvas,mCurPageBitmap); } // 绘制翻起页的阴影 void CPage::DrawCurrentPageShadow(SkCanvas *canvas) { double degree; if (mIsRTandLB) { degree = PI/4 - atan2(mBezierControl1.fY - mTouch.fY, mTouch.fX - mBezierControl1.fX); } else { degree = PI/ 4 - atan2(mTouch.fY - mBezierControl1.fY, mTouch.fX - mBezierControl1.fX); } // 翻起页阴影顶点与touch点的距离 double d1 = (float) 25 * 1.414 * cos(degree); double d2 = (float) 25 * 1.414 * sin(degree); float x = (float) (mTouch.fX + d1); float y; if (mIsRTandLB) { y = (float) (mTouch.fY + d2); } else { y = (float) (mTouch.fY - d2); } mPath1.reset(); mPath1.moveTo(x, y); mPath1.lineTo(mTouch.fX, mTouch.fY); mPath1.lineTo(mBezierControl1.fX, mBezierControl1.fY); mPath1.lineTo(mBezierStart1.fX, mBezierStart1.fY); mPath1.close(); float rotateDegrees; canvas->save(); canvas->clipPath(mPath0, SkRegion::Op::kXOR_Op); canvas->clipPath(mPath1, SkRegion::Op::kIntersect_Op); int leftx; int rightx; SkShader *mCurrentPageShadow; if (mIsRTandLB) { leftx = (int) (mBezierControl1.fX); rightx = (int) mBezierControl1.fX + 25; //mCurrentPageShadow = mFrontShadowDrawableVLR; } else { leftx = (int) (mBezierControl1.fX - 25); rightx = (int) mBezierControl1.fX + 1; //mCurrentPageShadow = mFrontShadowDrawableVRL; } mCurrentPageShadow = mFolderShadowDrawableRL; //*********************************************************需要重点尝试, //尝试使用LinearGradient; //SkPaint paint; //paint.setShader(SkShader *shader); //SkShader linearShader = SkGradientShader::CreateLinear(); //paint.setShader(linearShader); //中间加上旋转以及路径计算 //mPaint.setShader(mComposeShader); //canvas.drawRect(0, 0, imgwidth, imgheight, mPaint); //drawRect(rect范围是下面mCurrentPageShadow.SetBounds的参数值) //canvas->drawRoundRect() //程序原来的阴影是用GradientDrawable实现 //在android的源码中,GradientDrawable的具体实现是:graphics/drawable/GradientDrawable.java //ensureValidRect()函数中,如果GradiemtDrawable类型是LINEAR_GRADIENT, //GradientDrawable的成员mFillPaint: //mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1,colors, st.mPositions, Shader.TileMode.CLAMP)); //ensureValidRect()在GradientDrawable的draw(Canvas canvas)开始处调用 //**********************************************************8 //rotateDegrees = (float) Math.toDegrees(atan2(mTouch.x - mBezierControl1.x, mBezierControl1.y - mTouch.y)); rotateDegrees = (float)(atan2(mTouch.fX - mBezierControl1.fX, mBezierControl1.fY - mTouch.fY))*180/PI; //canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y); canvas->translate(mBezierControl1.fX, mBezierControl1.fY); canvas->rotate(rotateDegrees); canvas->translate(-mBezierControl1.fX, -mBezierControl1.fY); SkPaint paint; paint.setShader(mCurrentPageShadow); canvas->drawRectCoords(leftx,(int)(mBezierControl1.fY - mMaxLength), rightx,(int)(mBezierControl1.fY),paint); //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.fX, mTouch.fY); mPath1.lineTo(mBezierControl2.fX, mBezierControl2.fY); mPath1.lineTo(mBezierStart2.fX, mBezierStart2.fY); mPath1.close(); canvas->save(); canvas->clipPath(mPath0, SkRegion::Op::kXOR_Op); canvas->clipPath(mPath1, SkRegion::Op::kIntersect_Op); if (mIsRTandLB) { leftx = (int) (mBezierControl2.fY); rightx = (int) (mBezierControl2.fY + 25); //mCurrentPageShadow = mFrontShadowDrawableHTB; } else { leftx = (int) (mBezierControl2.fY - 25); rightx = (int) (mBezierControl2.fY + 1); //mCurrentPageShadow = mFrontShadowDrawableHBT; } //rotateDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl2.y - mTouch.y, mBezierControl2.x - mTouch.x)); rotateDegrees = (float)(atan2(mBezierControl2.fY - mTouch.fY, mBezierControl2.fX - mTouch.fX))*180/PI; //canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y); canvas->translate(mBezierControl2.fX, mBezierControl2.fY); canvas->rotate(rotateDegrees); canvas->translate(-mBezierControl2.fX, -mBezierControl2.fY); float temp; if (mBezierControl2.fY < 0) temp = mBezierControl2.fY - mHeight; else temp = mBezierControl2.fY; int hmg = (int) _hypot(mBezierControl2.fX, 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); // Log.i("hmg", "mBezierControl2.x " + mBezierControl2.x // + " mBezierControl2.y " + mBezierControl2.y); //mCurrentPageShadow.draw(canvas); if (hmg > mMaxLength) canvas->drawRectCoords((int)(mBezierControl2.fX - 25) - hmg, leftx,(int)(mBezierControl2.fX + mMaxLength) - hmg,rightx,paint); else canvas->drawRectCoords((int)(mBezierControl2.fX - mMaxLength),leftx,(int)(mBezierControl2.fX), rightx,paint); canvas->restore(); } //绘制翻起页背面 void CPage::DrawCurrentBackArea(SkCanvas *canvas, SkBitmap *bitmap) { int i = (int) (mBezierStart1.fX + mBezierControl1.fX) / 2; float f1 = abs(i - mBezierControl1.fX); int i1 = (int) (mBezierStart2.fY + mBezierControl2.fY) / 2; float f2 = abs(i1 - mBezierControl2.fY); float f3 = min(f1, f2); mPath1.reset(); mPath1.moveTo(mBeziervertex2.fX, mBeziervertex2.fY); mPath1.lineTo(mBeziervertex1.fX, mBeziervertex1.fY); mPath1.lineTo(mBezierEnd1.fX, mBezierEnd1.fY); mPath1.lineTo(mTouch.fX, mTouch.fY); mPath1.lineTo(mBezierEnd2.fX, mBezierEnd2.fY); mPath1.close(); SkShader *mFolderShadowDrawable; int left; int right; if (mIsRTandLB) { left = (int) (mBezierStart1.fX - 1); right = (int) (mBezierStart1.fX + f3 + 1); //mFolderShadowDrawable = mFolderShadowDrawableLR; } else { left = (int) (mBezierStart1.fX - f3 - 1); right = (int) (mBezierStart1.fX + 1); //mFolderShadowDrawable = mFolderShadowDrawableRL; } mFolderShadowDrawable =mFolderShadowDrawableRL; canvas->save(); canvas->clipPath(mPath0); canvas->clipPath(mPath1, SkRegion::Op::kIntersect_Op); mPaint.setColorFilter(mpColorMatrixFilter); float dis = (float)_hypot(mCornerX - mBezierControl1.fX,mBezierControl2.fY - mCornerY); float f8 = (mCornerX - mBezierControl1.fX) / dis; float f9 = (mBezierControl2.fY - 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.set(mMatrixArray); mMatrix.preTranslate(-mBezierControl1.fX, -mBezierControl1.fY); mMatrix.postTranslate(mBezierControl1.fX, mBezierControl1.fY); //canvas.drawBitmap(bitmap, mMatrix, mPaint); canvas->drawBitmapMatrix(*bitmap,mMatrix,&mPaint); mPaint.setColorFilter(NULL); //canvas.rotate(mDegrees, mBezierStart1.fX, mBezierStart1.fY); canvas->translate(mBezierStart1.fX, mBezierStart1.fY); canvas->rotate(mDegrees); canvas->translate(-mBezierStart1.fX, -mBezierStart1.fY); SkPaint paint; paint.setShader(mFolderShadowDrawable); canvas->drawRectCoords(left, (int) mBezierStart1.fY, right,(int) (mBezierStart1.fY + mMaxLength),paint); //mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.fY, right, // (int) (mBezierStart1.fY + mMaxLength)); //mFolderShadowDrawable.draw(canvas); canvas->restore(); } //public void computeScroll() { // super.computeScroll(); // if (mScroller.computeScrollOffset()) { // float x = mScroller.getCurrX(); // float y = mScroller.getCurrY(); // mTouch.x = x; // mTouch.y = y; // postInvalidate(); // } //} void CPage::StartAnimation(int delayMillis) { int dx, dy; // dx 水平方向滑动的距离,负值会使滚动向左滚动 // dy 垂直方向滑动的距离,负值会使滚动向上滚动 if (mCornerX > 0) { dx = -(int)(mWidth + mTouch.fX); } else { dx = (int)(mWidth - mTouch.fX + mWidth); } if (mCornerY > 0) { dy = (int) (mHeight - mTouch.fY); } else { dy = (int) (1 - mTouch.fY); // 防止mTouch.y最终变为0 } //mScroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy,delayMillis); } //退出animation void CPage::AbortAnimation() { //if (!mScroller.isFinished()) //{ // mScroller.abortAnimation(); //} } BOOL CPage::CanDragOver() { if (mTouchToCornerDis > mWidth / 10) return TRUE; return FALSE; } // 是否从左边翻向右边 BOOL CPage::DragToRight() { if (mCornerX > 0) return FALSE; return TRUE; } BOOL CPage::LButtonDown(SkCanvas *canvas,SkPoint pt) { CalcCornerXY(pt.fX,pt.fY); DrawPage(canvas,pt); return TRUE; } BOOL CPage::MouseMove(SkCanvas *canvas,SkPoint pt) { DrawPage(canvas,pt); return TRUE; } BOOL CPage::LButtonUp(SkCanvas *canvas,SkPoint pt) { // //if () //{ //} //pt.fX +=(1200-pt.fX); DrawPage(canvas,pt); //canvas->drawBitmap(*mNextPageBitmap,0,0,NULL); return TRUE; }
使用:
SkPoint mTouch; SkBitmap *pskBitmap; SkCanvas *pskCanvas; BITMAPINFO *lpbmi; HWND g_hWnd; SkBitmap *bkBitmap;//背景图片 SkBitmap *CurrentPageBmp; SkBitmap *NextPageBmp; SkCanvas *CurrentPageCanvas; SkCanvas *NextPageCanvas; CPage pageflip; SkRect g_rtImg;// 图片最初按钮。 SkRect g_rtClip;//矩阵裁剪用 ,做图片旋转时,每次旋转时的裁剪会用到上一次的裁剪范围。 //g_rtClip是共用裁剪范围,多个不同的位置共用,每次旋转前初始化为要旋转图片的原始位置 //初始化背景图片, void MyInitBkImage(char *filename) { SkFILEStream stream(filename); SkImageDecoder * coder = SkImageDecoder::Factory(&stream); if (coder) { bkBitmap = new SkBitmap(); coder->decode(&stream,bkBitmap,SkBitmap::kRGB_565_Config,SkImageDecoder::kDecodePixels_Mode); } } SkBitmap* MyInitImage(char *imgFileName) { SkBitmap *bitmap; SkFILEStream stream(imgFileName); SkImageDecoder * coder = SkImageDecoder::Factory(&stream); if (coder) { bitmap = new SkBitmap(); coder->decode(&stream,bitmap,SkBitmap::kRGB_565_Config,SkImageDecoder::kDecodePixels_Mode); return bitmap; } return NULL; } //整体初始化 void MyInit() { pskBitmap = new SkBitmap(); pskBitmap->setConfig(SkBitmap::kRGB_565_Config,800,480); pskBitmap->allocPixels();//分配位图所占空间 pskCanvas = new SkCanvas(); pskCanvas->setBitmapDevice(*pskBitmap); lpbmi = (BITMAPINFO*)malloc( sizeof(BITMAPINFO)+sizeof(RGBQUAD)*(2) ); //printf("%d,%d\n",sizeof(BITMAPINFOHEADER),sizeof(BITMAPINFO));40,44 memset( lpbmi, 0, sizeof(BITMAPINFO)+sizeof(RGBQUAD)*(2) );//必须同上方一直 lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);//位图信息头大小 40字节 lpbmi->bmiHeader.biWidth = 800; lpbmi->bmiHeader.biHeight = -480; lpbmi->bmiHeader.biPlanes = 1; lpbmi->bmiHeader.biBitCount = 16; //16位位图 565模式0xF800、0x07E0、0x001F lpbmi->bmiHeader.biCompression = BI_BITFIELDS; //压缩参数 BI_RGB=0表示无压缩, lpbmi->bmiHeader.biSizeImage = 0; lpbmi->bmiColors[0].rgbBlue = 0; lpbmi->bmiColors[0].rgbGreen = 0xF8; //248? lpbmi->bmiColors[0].rgbRed = 0; lpbmi->bmiColors[0].rgbReserved = 0; lpbmi->bmiColors[1].rgbBlue = 0xE0; //224 lpbmi->bmiColors[1].rgbGreen = 0x07; //7 lpbmi->bmiColors[1].rgbRed = 0; lpbmi->bmiColors[1].rgbReserved = 0; lpbmi->bmiColors[2].rgbBlue = 0x1F; //31 lpbmi->bmiColors[2].rgbGreen = 0; lpbmi->bmiColors[2].rgbRed = 0; lpbmi->bmiColors[2].rgbReserved = 0; MyInitBkImage("\\USER\\skia\\bk.png"); //MyInitBkImage("\\Storage Card\\bk.png"); g_rtImg.setLTRB(151,214,249,346); //初始化图片位置 //g_rtClip 在每次旋转前初始化 CurrentPageBmp = MyInitImage("\\USER\\skia\\book.png"); NextPageBmp = MyInitImage("\\USER\\skia\\book.png"); pageflip.SetBitmaps(CurrentPageBmp,NextPageBmp); CurrentPageCanvas = new SkCanvas(); CurrentPageCanvas->setBitmapDevice(*CurrentPageBmp); NextPageCanvas = new SkCanvas(); NextPageCanvas->setBitmapDevice(*NextPageBmp); SkPaint *paint = new SkPaint(); paint->setTextSize(24); paint->setColor(SK_ColorWHITE); paint->setTextAlign(SkPaint::Align::kLeft_Align); //paint->breakText() for (int i=0;i<10;i++) { CurrentPageCanvas->drawText("the first page,hello ,no. 11",40,30,30+30*i,*paint); NextPageCanvas->drawText("Test Microsoft Visual Studio", 40,30,30+30*i,*paint); } } //画到屏幕上 void Flip() { HDC dc = GetDC(g_hWnd); SetDIBitsToDevice(dc, 0, 0, 800, 480, 0, 0, 0, 800, pskBitmap->getPixels(), lpbmi, DIB_RGB_COLORS); ReleaseDC(g_hWnd,dc); } //画图片filename,rt为其范围,图片没有保存,每次临时加载 void DrawImage(char * filename,SkCanvas *canvas, SkRect rt, SkPaint *paint) { int ti = GetTickCount(); SkFILEStream stream(filename); SkImageDecoder* coder = SkImageDecoder::Factory(&stream); SkBitmap *bitmap; if (coder) { //printf(" file %s code success\n",filename); bitmap = new SkBitmap(); coder->decode(&stream, bitmap, SkBitmap::kRGB_565_Config, SkImageDecoder::kDecodePixels_Mode); } else { printf(" file %s code fail\n",filename); return; } //printf("24bit800*480png,code time =%d\n",GetTickCount()-ti);//367 ti = GetTickCount(); canvas->drawBitmap(*bitmap,rt.fLeft, rt.fTop); //printf("24bit800*480png,draw time =%d\n",GetTickCount()-ti);//12 delete bitmap; return; } void MyLButtonDown(POINT pt) { float x = pt.x; float y = pt.y; SkPoint touch; touch.fX =x; touch.fY =y; pageflip.LButtonDown(pskCanvas,touch); Flip(); } void MyMouseMove(POINT pt) { float x = pt.x; float y = pt.y; SkPoint touch; touch.fX =x; touch.fY =y; pageflip.MouseMove(pskCanvas,touch); Flip(); }
我用的win32工程。
在InitInstance函数中加上:
g_hWnd = hWnd; MyInit(); //never forget ShowWindow(hWnd, nCmdShow); MoveWindow(hWnd,0,0,800,480,1);
WndProc函数中:
case WM_LBUTTONDOWN: { RECT rt = {700,0,800,100}; POINT pt; pt.x =LOWORD(lParam);pt.y = HIWORD(lParam); printf("pt:x=%d,y=%d\n",pt.x,pt.y); printf("rt:%d,%d,%d,%d\n",rt.left,rt.top,rt.right,rt.bottom); if (PtInRect(&rt,pt)==TRUE) { //EndDialog(hWnd,IDOK); PostQuitMessage(0); } else { printf("xxxxxxxxx\n"); } MyLButtonDown(pt); //UpdateWindow(hWnd); } break; case WM_MOUSEMOVE: { RECT rt = {700,0,800,100}; POINT pt; pt.x =LOWORD(lParam);pt.y = HIWORD(lParam); MyMouseMove(pt); }break;
代码效果:
ezhong的博客园:http://www.cnblogs.com/ezhong/
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ezhong的博客签名-------------------------------------
以上内容来自ezhong的博客园,作者:ezhong
ezhong的博客园: http://www.cnblogs.com/ezhong
感谢您的阅读。感谢您的分享。