Canvas的用法总结
我们先来看一下Canvas类的介绍:Canvas是用来主持绘画操作的类,如果想要画些东西,你需要4个组件:一个保存像素的Bitmap,一个主持绘画操作的Canvas(往Bitmap写东西),一个绘制的基本元素(例如Rect,Path,Text,Btimap),一支画笔(用来描述绘画的颜色与风格)。
英语水平有限...
从Canvas类的描述来看,Canvas是用来做绘画操作的,那我们来看一下Canvas有哪些绘画操作(以下绘制的Paint默认为stroken风格):
Canvas的绘制功能
drawArc:绘制圆弧
/** * @param 圆弧的整个矩形范围 * @param 开始角度 * @param 扫描多少角度 * @param 是否包含中心点 * @param 绘制的画笔 */canvas?.drawArc(RectF(0f, 0f, 500f, 300f), 30f, 90f, false, mPaint)复制代码
drawARGB:绘制颜色
/** * @param alpha值0-255 * @param 红色值0-255 * @param 绿色值0-255 * @param 蓝色值0-255 */canvas?.drawARGB(255, 255, 123, 87)复制代码
drawBitmap:绘制位图
/** * @param 要绘制的bitmap * @param 开始绘制的left * @param 开始绘制的right * @param 绘制的paint */canvas?.drawBitmap(bitmap, 100f, 100f, mPaint)复制代码
/** * @param 要绘制的bitmap * @param 绘制源的矩形(确定要绘制的图片的子集,绘制图片的部分信息,为null时绘制整个bitmap) * @param 绘制目标的矩形(通过缩放拉伸,将绘制信息绘制到目标区域) * @param 绘制的paint */canvas?.drawBitmap(bitmap, Rect(0, 0, bitmap.width / 2, bitmap.height / 2), Rect(50, 50, 500, 500), mPaint)复制代码
drawBtimap还有个高级用法,drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint),这个涉及到Matrix时在说
drawCircle:绘制圆
/** * @param 绘制圆中心x坐标 * @param 绘制圆中心y坐标 * @param 绘制圆的半径 * @param 绘制的paint */canvas?.drawCircle(100f, 100f, 50f, mPaint)复制代码
drawColor:绘制颜色
/** * @param 绘制圆中心x坐标 * @param 绘制圆中心y坐标 * @param 绘制圆的半径 * @param 绘制的paint */canvas?.drawColor(Color.GRAY)复制代码
这个很简单,跟drawARGB是差不多的,不过他还有一个重载方法,需要传入一个PorterDuff.Mode,我们用下面一张图来看看PorterDuff.Mode不同模式的效果
这个模式在paint里面会比较常用,我们在paint里面在实际使用看看效果drawLine:绘制直线
/** * @param 起始点x坐标 * @param 起始点y坐标 * @param 终结点x坐标 * @param 终结点y坐标 * @param 绘制的paint */canvas?.drawLine(0f, 0f, 100f, 300f, mPaint)复制代码
/** * @param 需要绘制的数组,必须是4的倍数,跟drawLine设置点一样 * @param 绘制的paint */canvas?.drawLines(floatArrayOf(0f, 0f, 100f, 300f, 50f, 50f, 200f, 300f), mPaint)复制代码
drawOval:绘制椭圆
/** * @param 绘制椭圆的矩形 * @param 绘制的paint */canvas?.drawOval(RectF(0f, 0f, 300f, 100f), mPaint)复制代码
drawRect:绘制矩形
绘制矩形参数跟绘制椭圆一样,很简单
drawPoint:绘制点
绘制点需要制定点的xy坐标就可以
drawText:绘制文字
/** * @param 绘制的文字 * @param 起始点x * @param 文字的基准线y * @param 绘制的paint */canvas?.drawText("kevinxie", 10f, 200f, mPaint)复制代码
drawPath:绘制路径
val path = Path()path.lineTo(0f, 100f)path.lineTo(100f, 100f)/** * @param 绘制的路径 * @param 绘制的paint */canvas?.drawPath(path, mPaint)复制代码
canvas的绘画操作大致就这么多了,canvas还有变形的功能
Canvas的变形功能
translate:平移
canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)/** * @param x方向平移的距离 * @param y方向平移的距离 */canvas?.translate(100f, 100f)canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)复制代码
scale:缩放
canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)/** * @param x方向平移的距离 * @param y方向平移的距离 */canvas?.scale(0.8f, 0.8f, 600f, 600f)canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)复制代码
rotate:旋转
canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)/** * @param 旋转的角度 * @param 旋转中心点的x左边点 * @param 旋转中心点的y左边点 */canvas?.rotate(30f, 700f, 700f)canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)复制代码
skew:错切
canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)/** * @param x方向的错切量 * @param y方向的错切量 */canvas?.skew(0.5f, 0f)canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)复制代码
Canvas还可以利用Matrix来完成变换,在后面再看看Matrix的作用
Canvas的裁剪功能
clipRect:矩形裁剪
/** * @param 裁剪的矩形 */canvas?.clipRect(Rect(150, 150, 400, 400))canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)复制代码
clipRect:路径裁剪
val path = Path()path.addCircle(300f, 300f, 100f, Path.Direction.CW)/** * @param 裁剪的路径 */canvas?.clipPath(path)canvas?.drawBitmap(bitmap, null, Rect(50, 50, 500, 500), mPaint)复制代码
Canvas的save、restore
save(): 用来保存Canvas的状态,save()方法之后的代码,可以调用Canvas的平移、放缩、旋转、裁剪等操作! restore():用来恢复Canvas之前保存的状态(可以想成是保存坐标轴的状态),防止save()方法代码之后对Canvas执行的操作,继续对后续的绘制会产生影响,通过该方法可以避免连带的影响
多次调用save来保存Canvas的状态,状态信息会以栈结构进行存储,每次调用restore都会恢复到上一存储状态,你可以使用restoreToCount来直接指定要恢复到哪一次状态
override fun onDraw(canvas: Canvas?) { canvas?.save() canvas?.rotate(30f) mPaint.color = Color.RED canvas?.drawLine(0f, 0f, 100f, 0f, mPaint) canvas?.save() mPaint.color = Color.GREEN canvas?.rotate(30f) canvas?.drawLine(0f, 0f, 100f, 0f, mPaint) canvas?.save() mPaint.color = Color.BLUE canvas?.rotate(30f) canvas?.drawLine(0f, 0f, 100f, 0f, mPaint) canvas?.restoreToCount(1) mPaint.color = Color.BLACK canvas?.drawLine(0f, 0f, 100f, 0f, mPaint)}复制代码
save还有一个重载的方法,需要传一个saveFlag,这些Flag标识的意义和使用范围如下:
我们上面说到的变换功能就是对canvas的matrix信息进行变换,裁剪功能就是对canvas的大小信息进行变换。 save的两个函数和saveLayer的两个函数不同之处在于saveLayer会新建一个layer(图层)canvas?.drawColor(Color.RED)/** * @param 图层信息存储的bitmap大小 * @param 画笔 * @param saveFlag */canvas?.saveLayer(RectF(0f, 0f, 500f, 500f), mPaint, Canvas.ALL_SAVE_FLAG)canvas?.rotate(30f)mPaint.style = Paint.Style.FILLmPaint.color = Color.GREENcanvas?.drawRect(Rect(0, 0, 800, 800), mPaint)canvas?.restore()mPaint.style = Paint.Style.STROKEcanvas?.drawRect(Rect(0, 0, 800, 800), mPaint)复制代码
以上就是canvas的一些主要的用法了