canvas教程

从零开始实现书籍翻页效果(四)(2)

字号+ 作者:H5之家 来源:H5之家 2017-11-09 15:08 我要评论( )

由之前这张图可以看出来C区域阴影的绘制过程其实是和B区域差不多的,不同的地方在于颜色由深到浅的渐变方向变成垂直cj向a点方向,且阴影矩形的短边长度变为与ce或jh(取短的那个)长度相关,因为原理一样,就不再赘

由之前这张图可以看出来C区域阴影的绘制过程其实是和B区域差不多的,不同的地方在于颜色由深到浅的渐变方向变成垂直cj向a点方向,且阴影矩形的短边长度变为与ce或jh(取短的那个)长度相关,因为原理一样,就不再赘述了,下面是绘制C区域阴影的代码(注意对比分析不同于绘制B区域阴影方法的地方)

/** * 绘制C区域内容 * @param canvas * @param pathA * @param pathPaint */ private void drawPathCContent(Canvas canvas, Path pathA, Paint pathPaint){ Bitmap contentBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565); Canvas contentCanvas = new Canvas(contentBitmap); //下面开始绘制区域内的内容... contentCanvas.drawPath(getPathB(),pathPaint);//绘制一个背景,path用B的就行 contentCanvas.drawText("这是在A区域的内容...AAAA", viewWidth-260, viewHeight-100, textPaint); //结束绘制区域内的内容... canvas.save(); canvas.clipPath(pathA); canvas.clipPath(getPathC(), Region.Op.REVERSE_DIFFERENCE);//裁剪出C区域不同于A区域的部分 float eh = (float) Math.hypot(f.x - e.x,h.y - f.y); float sin0 = (f.x - e.x) / eh; float cos0 = (h.y - f.y) / eh; //设置翻转和旋转矩阵 float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f }; mMatrixArray[0] = -(1-2 * sin0 * sin0); mMatrixArray[1] = 2 * sin0 * cos0; mMatrixArray[3] = 2 * sin0 * cos0; mMatrixArray[4] = 1 - 2 * sin0 * sin0; Matrix mMatrix = new Matrix(); mMatrix.reset(); mMatrix.setValues(mMatrixArray);//翻转和旋转 mMatrix.preTranslate(-e.x, -e.y);//沿当前XY轴负方向位移得到 矩形ABCD mMatrix.postTranslate(e.x, e.y);//沿原XY轴方向位移得到 矩形A4 B4 C4 D4 canvas.drawBitmap(contentBitmap, mMatrix, null); drawPathCShadow(canvas);//调用绘制阴影方法 canvas.restore(); } /** * 绘制C区域阴影,阴影左浅右深 * @param canvas */ private void drawPathCShadow(Canvas canvas){ int deepColor = 0xff111111;//为了让效果更明显使用此颜色代码,具体可根据实际情况调整 // int deepColor = 0x55333333; int lightColor = 0x00333333; int[] gradientColors = {lightColor,deepColor};//渐变颜色数组 int deepOffset = 1;//深色端的偏移值 int lightOffset = -30;//浅色端的偏移值 float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//view对角线长度 int midpoint_ce = (int) (c.x + e.x) / 2;//ce中点 int midpoint_jh = (int) (j.y + h.y) / 2;//jh中点 float minDisToControlPoint = Math.min(Math.abs(midpoint_ce - e.x), Math.abs(midpoint_jh - h.y));//中点到控制点的最小值 int left; int right; int top = (int) c.y; int bottom = (int) (viewDiagonalLength + c.y); GradientDrawable gradientDrawable; if (style.equals(STYLE_TOP_RIGHT)) { gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors); gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); left = (int) (c.x - lightOffset); right = (int) (c.x + minDisToControlPoint + deepOffset); } else { gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors); gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); left = (int) (c.x - minDisToControlPoint - deepOffset); right = (int) (c.x + lightOffset); } gradientDrawable.setBounds(left,top,right,bottom); float mDegrees = (float) Math.toDegrees(Math.atan2(e.x- f.x, h.y - f.y)); canvas.rotate(mDegrees, c.x, c.y); gradientDrawable.draw(canvas); }

效果如图

绘制当前页(A区域)的阴影

当从右上或右下翻页时,A区域的阴影由两部分组成,这在之前的图中已经标出来了。根据阴影效果的需求,方案不同,绘制的复杂度也不同,这里就以我自己的方案为例进行讲解

先来看左边部分的阴影区域,按照之前绘制阴影过程的分析,我们直接代入相关条件即可。此时阴影矩形短边长度为d点到直线ae的距离的二分之一,旋转中心为e,旋转角度为Math.toDegrees(Math.atan2(e.x-a.x, a.y-e.y)),根据条件,修改BookPageView

public class BookPageView extends View { //省略部分代码... float lPathAShadowDis = 0;//A区域左阴影矩形短边长度参考值 /** * 绘制A区域内容 * @param canvas * @param pathA * @param pathPaint */ private void drawPathAContent(Canvas canvas, Path pathA, Paint pathPaint){ Bitmap contentBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565); Canvas contentCanvas = new Canvas(contentBitmap); //下面开始绘制区域内的内容... contentCanvas.drawPath(pathA,pathPaint); contentCanvas.drawText("这是在A区域的内容...AAAA", viewWidth-260, viewHeight-100, textPaint); //结束绘制区域内的内容... canvas.save(); canvas.clipPath(pathA, Region.Op.INTERSECT);//对绘制内容进行裁剪,取和A区域的交集 canvas.drawBitmap(contentBitmap, 0, 0, null); drawPathALeftShadow(canvas,pathA); canvas.restore(); } /** * 绘制A区域左阴影 * @param canvas */ private void drawPathALeftShadow(Canvas canvas, Path pathA){ canvas.restore(); canvas.save(); int deepColor = 0x33333333; int lightColor = 0x01333333; int[] gradientColors = {lightColor,deepColor};//渐变颜色数组 int left; int right; int top = (int) e.y; int bottom = (int) (e.y+viewHeight); GradientDrawable gradientDrawable; if (style.equals(STYLE_TOP_RIGHT)) { gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors); gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); left = (int) (e.x - lPathAShadowDis /2); right = (int) (e.x); } else { gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors); gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); left = (int) (e.x); right = (int) (e.x + lPathAShadowDis /2); } gradientDrawable.setBounds(left,top,right,bottom); float mDegrees = (float) Math.toDegrees(Math.atan2(e.x-a.x, a.y-e.y)); canvas.rotate(mDegrees, e.x, e.y); gradientDrawable.draw(canvas); } /** * 计算各点坐标 * @param a * @param f */ private void calcPointsXY(MyPoint a, MyPoint f){ //省略部分代码... //计算d点到直线ae的距离 float lA = a.y-e.y; float lB = e.x-a.x; float lC = a.x*e.y-e.x*a.y; lPathAShadowDis = Math.abs((lA*d.x+lB*d.y+lC)/(float) Math.hypot(lA,lB)); } }

效果如图

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Firefox58版火狐浏览器将允许用户阻止Canvas指纹追踪

    Firefox58版火狐浏览器将允许用户阻止Canvas指纹追踪

    2017-11-09 10:03

  • 【canvas图片裁剪360页面上怎么有一条黑线】

    【canvas图片裁剪360页面上怎么有一条黑线】

    2017-11-08 14:00

  • Firefox将增强Canvas指纹追踪技术的防御能力

    Firefox将增强Canvas指纹追踪技术的防御能力

    2017-11-07 10:07

  • 如何利用canvas模仿百度贴吧客户端loading小球?

    如何利用canvas模仿百度贴吧客户端loading小球?

    2017-11-06 16:08

网友点评
>