手写谷歌浏览器图标
不规则图形绘制
谷歌浏览器的图标是一个不规则图形,今天来手动实现它
1、首先自定义View,然后定义各种需要的参数:
private int[] colors = new int[]
{0xFFD21D22,0xFFFBD109,0xFF4BB748,0xFF398ED5,Color.WHITE}; //定义google的颜色
private int cx; //google圆心x坐标
private int cy; //google圆心y坐标
private int mWidth; //控件宽度
private int mHeight; //控件高度
private Paint mPaint; //画笔
private Path mPath; //线段
private int wholeRadius = 300; //最外圆半径
private int outerRadius = 150; //外圆半径
private float innerRadius = 120; //内圆半径
private RectF wholeRectF; //最外圆内接矩形
private RectF outerRectF; //外圆内接矩形
private Bitmap mBitmap; //画板
private Canvas mCanvas;
private Matrix matrix; //用于旋转的变换矩阵
2、接着对这些值进行初始化:
public void init(){
cx = getLeft() + mWidth / 2;
cy = getTop() + mHeight / 2;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //生成画笔对象并设置抗锯齿
mPath = new Path();
wholeRectF = new RectF(cx - wholeRadius,cy - wholeRadius,cx + wholeRadius,cy + wholeRadius);
outerRectF = new RectF(cx - outerRadius,cy - outerRadius, cx + outerRadius, cy + outerRadius);
mBitmap = Bitmap.createBitmap(mWidth,mHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
matrix = new Matrix();
}
圆心的坐标cx,cy,值分别为left + getWidth /2,top + getHeight / 2
wholeRectF和outerRectF分别为图形(因为图形本身就是个圆)的外界矩形和内圆的外接矩形。传入相对于x,y坐标的left、right、top、bottom的值就能生成对象。mBitmap的初始化可以理解为生成一张空白的画布,Canvas类似于画板,然后通过mCanvas = new Canvas(mBitmap) 将画布“放在”画板上,就可以进行绘画操作了。
3、接着就可以“画出”浏览器图标了
首先通过观察图形,可以发现其他它的外围是有三块相同的不规则图形旋转组成:
如图,蓝色线条包围的区域,选择120度后就组成了图形的外围。
我们的目标只要画出一块图形即可。
接下来如图,黑色表示整个图形的半径,紫色表示中间的圆(包括白色和蓝色部分)半径,绿色表示最内圆(蓝色)半径,
令白色圆的半径设置为图形了一半。
--------------------------------分割线--------------------------------
使用Path类,Path是线性路径,可以根据指定的点画出不规则图形,绘制路线为AB、BC、CD、DA:
//绘制红色
mPaint.setColor(colors[0]);
mPath.addArc(outerRectF,150,120);
mPath.lineTo((float) (cx + Math.sqrt(3) / 2 * wholeRadius),cy - outerRadius);
mPath.addArc(wholeRectF,-30,-120);
mPath.lineTo((float) (cx - Math.sqrt(3) / 2 * outerRadius),cy + outerRadius / 2f);
mPaint.setStyle(Paint.Style.FILL);
mCanvas.drawPath(mPath,mPaint);
画AB
设置画笔的颜色为红色,然后使用addArc勾勒出一段圆弧(AB),第一个参数为圆的外接矩形,在上面已经定义,第二、三个参数表示以那个角度开始顺时针扫视,那个角度开始结束。以3点钟方向开始。举例:
这个图形是从0°开始,顺时针270°结束,因此就是:addArc(外接圆参数,0,270);
这个图形从180°开始,顺时针225°结束,因此就是:addArc(外接圆参数,180,225);
画BC
回到代码中,AB线完成后,截至使用lineTo完成BC段,功能如它的名字一样,Path会连接到哪个点,因此将C点的坐标传入lineTo中。因为这是一个60°,30°内角的特殊三角形,根据三角函数可以得出长度。
C点的x坐标是cx(圆心x坐标) + 根号3 / 2 * 整个图形的半径(上图中黑色的线段)
y坐标是cy(圆心y坐标) - 1 /2 * 整个图形的半径(上图中黑色的线段)
画CD
与画AB一样,这里采用逆时针-30 °~ -120°画出CD圆弧,其实这与210° ~ 330°是完全一样的。
画DA
其实这时的Path已经完成了整个区域的绘制,只要将它完成闭合即可,即:连接A点。因为三角形的特殊性,根据三角函数可以轻易的得到各边长度。中间圆半径(对应上图紫色线段)作为三角形的斜边.
A点x坐标为:cx - 根号3 / 2 * 中间圆半径
y坐标为:cy + 1/2 * 中间圆半径
最后通过canvans对象的drawPath方法完成Path的绘制
至此,一个不规则图形已经完成。
接着,借用Matrix矩阵的rotate方法绕着圆心旋转120°,接着调用Path的transform方法传入这个矩阵即可完成剩余2个图形的绘制(因为都是一样的)。
matrix.setRotate(120,cx,cy);
mPath.transform(matrix);
中间的圆,只要调用drawCircle方法即可。
demo地址:https://github.com/lyx19970504/IrregularView