Android 实现书籍翻页效果---番外篇之光影效果

             By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处

       对于之前发布的翻页效果的源码,由于写得太匆忙,注释讲解的不多,且本人文笔较差,至使很多人对其中的很多部分不是很清楚,尤其是其中的光影部分,而我也不知道如何去向其解释,真是让我汗颜无比,所以今天利用闲暇来给大家分析一下。

    ps: 由于零碎时间有限所以文字也有些零碎,望见谅~

     首先来分析,翻起页与下一页交汇处的阴影,即下图(红圈标注处):

                   

   上图是经过选择canvas.rotate和canvas.clipPath得到的,

         

      变量标注图:

        

 

 

 

现在我们来还原未进行上述操作前的样子。得到下图:

            

     蓝色选择区域为mPath0,绿色所选区域为mPath1。执行canvas.clipPath(mPath0);canvas.clipPath(mPath1, Region.Op.INTERSECT);   即只绘制在mPath0和mPath1相交的区域。蓝色边框和绿色边框相交的区域。

      让我们在回到canvas.rotate之前看看。

            

 

       旋转前阴影的位置位于图片外,图的下边,图中的mDegrees约为-128°,所以执行canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);即画布逆时针旋转-128°之后即可以得到图中的倾斜的阴影。

      图中阴影的宽度为mTouchToCornerDis / 4, 其中mTouchToCornerDis为touch点与其靠近的翻起角的直线距离,这样就可以实现,Touch如果越远离翻起角,那么阴影的宽度就会越大;阴影的长度为mMaxLength,这是屏幕对角线的长度,因为我假定阴影在接近屏幕对角线时到达最大,即我的屏幕是480*800,那么mMaxLength= Math.hypot(480, 800);

        哈哈,说道这里大家应该明白了吧,下边的其他阴影效果也是大同小异的。大家可以自己琢磨下。还有就是因为阴影的位置与mBezierStart1.x, mBezierStart1.y是有关联的,当mBezierStart1.x<0且到一定程度时,会出现一些bug,所以我在calcPoints()中,对(mBezierStart1.x < 0 || mBezierStart1.x > 480)进行了限制。如果大家试着屏蔽calcPoints()中if(mBezierStart1.x < 0 || mBezierStart1.x > 480)便会出现以下这种类似的情况。

                   

要如图所示,交汇页的阴影有一半显示不出来,那是因为mBezierStart1.x为负数,之前假定的阴影最大长度是基于mBezierStart1.x最小为0时的,当mBezierStart1.x为负数且小到一定程度时,阴影的长度就不足以绘制完整啦。大家如果需要实现向上图的那种翻页角度的话,需要自己重新计算下阴影绘制的起点坐标。

 

O(∩_∩)O哈! 好啦,就说到这里,大家如果有什么不明白,或者代码中的错误,欢迎指出!!

 

翻页效果,导入源码即可运行。 package sf.hmg.turntest; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.graphics.Region; import android.graphics.drawable.GradientDrawable; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class PageWidget extends View { private static final String TAG = "hmg"; private int mWidth = 480; 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(480, 800); int[] mBackShadowColors; int[] mFrontShadowColors; GradientDrawable mBackShadowDrawableLR; GradientDrawable mBackShadowDrawableRL; GradientDrawable mFolderShadowDrawableLR; GradientDrawable mFolderShadowDrawableRL; GradientDrawable mFrontShadowDrawableHBT; GradientDrawable mFrontShadowDrawableHTB; GradientDrawable mFrontShadowDrawableVLR; GradientDraw
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值