赞
踩
Canvas:The Canvas class holds the “draw” calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).
根据doc的介绍我们可以看到canvas是画集合图形的一个重要类,它持有draw动作(就是画图).使用draw的时候我们需要4个基本条件:
1. 一个用来保存像素的Bitmap
2. Canvas
用来调用draw方法
3. 我们要画的材料(Rect,Path,Text,Bitmap,Color…)
4. Paint,用来设置内容的色值,样式,透明度…
这是根据文档中的介绍而翻译的,但是我们可以仔细瞅瞅,平时我们的自定义view也就是这个条件,例子我就列举了,随便找个自定义view就可以发现都是这么做的.
MATRIX_SAVE_FLAG,CLIP_SAVE_FLAG在使用save(flag)时被调用
ALL_SAVE_FLAG,CLIP_TO_LAYER_SAVE_FLAG,FULL_COLOR_LAYER_SAVE_FLAG,HAS_ALPHA_LAYER_SAVE_FLAG在使用saveLayer()或者saveLayerAlpha时调用.
我们可以使用如下code来进行测试:
...
canvas?.save(Canvas.flag);
...
canvas?.draw()...
canvas?.restore();
...
canvas?.draw()
Canvas(Bitmap bitmap) == Canvas() + setBitmap(Bitmap bitmap)
裁剪:clipPath();clipRect()
在介绍裁剪前,我们先介绍一下region这个类.
用于指定的几何区域剪裁区域图。
组合两个区域时可以执行的逻辑操作,既在多个裁剪区域发生重叠时,可以使用该类来实现我们需要的功能,如果是单个图形裁剪时,各个值对应显示的裁剪形状相同,同时,clip()都有默认值
我们可以举例:有A和B两个几何图形,对他们进行裁剪,同时他们相交,B使用Region.Op指定
注:该部分的含义我们可以从SkRegion.h
中的注释了解,如果想要理解具体内容的话,可以自己研究SkRegion.h,SkRegion.cpp
/**
* The logical operations that can be performed when combining two regions.
*/
enum Op {
kDifference_Op, //!< subtract the op region from the first region
kIntersect_Op, //!< intersect the two regions
kUnion_Op, //!< union (inclusive-or) the two regions
kXOR_Op, //!< exclusive-or the two regions
/** subtract the first region from the op region */
kReverseDifference_Op,
kReplace_Op, //!< replace the dst region with the op region
kLastOp = kReplace_Op
};
注意:op指的是我们裁剪时,裁剪完后显示的图形区域.如果clip()中没有使用Region.Op时,我们可以去Canvas中看看,一般都有默认Region.Op被调用
示例:
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.save()
canvas?.translate(5f, 5f)
paint.setColor(Color.parseColor("#00ff00"))
canvas?.drawRect(RectF(0f, 0f, 300f, 300f), paint)
canvas?.drawCircle(300f, 300f, 150f, paint)
paint.setColor(Color.parseColor("#ff0000"))
// 对一个矩形进行裁剪
canvas?.clipRect(RectF(0f, 0f, 300f, 300f))
val mPath = Path()
mPath.addCircle(300f, 300f, 150f, Path.Direction.CCW)
// 对指定的path进行裁剪
canvas?.clipPath(mPath, Region.Op.INTERSECT)
// 显示裁剪内容
canvas?.drawRect(RectF(0f, 0f, Integer.MAX_VALUE.toFloat(), Integer.MAX_VALUE.toFloat()), paint)
canvas?.restore()
}
我们可以看到Rect裁剪和Path裁剪完后显示出来的内容
注意:使用完clip()后,必须使用canvas.draw(),才可以把我们要裁剪的内容画出来
效果图:
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.save()
canvas?.translate(5f, 5f)
var width: Int = bitmap.width
var hegith: Int = bitmap.height
var radius: Int
when {
width < hegith -> radius = width / 2
width > hegith -> radius = hegith / 2
else -> radius = width / 2
}
var path = Path()
// path.addCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), Path.Direction.CW)
path.addRoundRect(RectF(0f, 0f, width.toFloat(), hegith.toFloat()), 30f, 30f, Path.Direction.CW)
canvas?.clipPath(path, Region.Op.INTERSECT)
canvas?.drawBitmap(bitmap, 0f, 0f, paint)
canvas?.restore()
}
我记得前边写过这种图形,其中一个是BitmapShader,如果有兴趣的话可以去看看这个类,这个类可以实现图片的各种形状.
canvas.clipPath()也可以根据Path绘制各种形状的图片,例如五角星,三角形,正方形…….
paint.setShader(BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP))
canvas?.drawRect(0f, 0f, 600f, 300f, paint)
paint.setShader(null)
paint.color = Color.parseColor("#4400ff00")
canvas?.clipRect(50, 20, 550, 280)
canvas?.drawRect(0f, 0f, Float.MAX_VALUE, Float.MAX_VALUE, paint)
canvas?.restore()
paint.setShader(BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP))
paint.color = Color.RED
canvas?.clipRect(50, 20, 400, 200)
canvas?.drawRect(0f, 0f, 600f, 300f, paint)
paint.setShader(null)
这个就不举例子了,最上面的那个就是,如果有兴趣的话,可以自己找些例子看看,或者自己写写
这个也不举例了,把上面的代码复制一份,将clip()修改为clipOut()就可以了,注意这个clipOut()需要运行在API26版本上.
动画:移动(translate),旋转(rotate),缩放(scale),错切(skew);矩阵(Matrix)变换(translate,rotate,scale,skew)
canvas的几何变换实际上还是对画布的矩阵进行改变来实现目地的
例:
/**
* Preconcat the current matrix with the specified translation
*
* @param dx The distance to translate in X
* @param dy The distance to translate in Y
*/
public
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。