先初始化画笔,注意此时画笔需要设置成空心:
/** * 初始化画笔 */ private void initPaint() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 将画笔设置为空心 mPaint.setStyle(Style.STROKE); // 设置画笔颜色 mPaint.setColor(Color.BLACK); // 设置画笔宽度 mPaint.setStrokeWidth(mLineWidth); } 然后循环的将画布缩放的同时绘制原正方形: /** * 绘制正方形 * * @param canvas */ private void drawSquare(Canvas canvas) { for (int i = 0; i < TOTAL_SQUARE_COUNT; i++) { // 保存画布 canvas.save(); float fraction = (float) i / TOTAL_SQUARE_COUNT; // 将画布以正方形中心进行缩放 canvas.scale(fraction, fraction, mHalfWidth, mHalfHeight); canvas.drawRect(mSquareRect, mPaint); // 画布回滚 canvas.restore(); } }一起来看下绘制的效果:其实最终效果和网上找的还是有点小差别的,由于画布的缩放,越小的时候画笔宽度越细,而原图是所有的都一样宽度,但似乎画笔宽度缩放之后效果更佳,哈哈 ... ...
三、canvas.rotate( ) - 画布的旋转:
canvas.rotate( )和canvas.scale()可以类比起来看,如果理解了canvas.scale( ),那么canvas.rotate( )将会非常简单实用;
简单来讲,canvas.rotate( )即是将画布进行旋转,和canvas.scale( )类似的是,它也有两个可以使用的方法:
/** * Preconcat the current matrix with the specified rotation. * * @param degrees The amount to rotate, in degrees */ public native void rotate(float degrees); /** * Preconcat the current matrix with the specified rotation. * * @param degrees The amount to rotate, in degrees * @param px The x-coord for the pivot point (unchanged by the rotation) * @param py The y-coord for the pivot point (unchanged by the rotation) */ public final void rotate(float degrees, float px, float py) { translate(px, py); rotate(degrees); translate(-px, -py); }两个方法的区别也是在于基准点的选取,默认是以原点作为基准点,另一个则是以传入的x,y 作为基准点,是不是和scale 一模一样,咱们一起来rotate一下:
咱们先转转左上角的矩形,转多少度呢?先来个90度玩玩吧;
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLUE); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); mPaint.setColor(Color.YELLOW); canvas.rotate(90); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); } 我们的预期是屏幕上有个旋转了的骚黄色矩形,一起来看看;
擦,黄色的矩形呢?
由于基准点是原点,我们直接旋转了90 度,所以已经将矩形旋转出屏幕,当然看不到了,我们将角度调小一点,改为45 度:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLUE); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); mPaint.setColor(Color.YELLOW); canvas.rotate(45); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); }此时我们可以可以清楚的看到黄色的矩形是红色矩形绕原点(0,0)旋转45度之后的结果;
我们再将旋转基准点改为矩形中心看看:
canvas.rotate(45,200,200);可以看到现在黄色矩形是红色矩形绕着中心旋转后的结果:
到这里,我们已经了解了canvas.rotate(float degrees)和 canvas.rotate(float degrees,float px , float py)的使用,同样也应该清楚后者的实现如下: translate(px, py); rotate(degrees); translate(-px, -py);
好了,我们再利用canvas.rotate()完成个闹钟表盘的小例子:
闹钟表盘其实和刻度尺类似,只是一个是在一条直线上绘制,一个是在一个圆周上绘制,说到底都是确定一个位置绘制刻度线;
既然是圆周,最简单的方式莫过于在闹钟的12点钟处划线,通过canvas的旋转绘制到对应圆周处,我们一起实现一下:
整个圆周是360 度,每隔 30 度为一个整时间刻度,整刻度与刻度之间有四个短刻度,划分出5个小段,每个段为6度,有了这些分析,我们则可以采用如下代码进行绘制:
/** * 绘制刻度 * * @param canvas */ private void drawLines(Canvas canvas) { for (int i = 0; i <= 360; i++) { if (i % 30 == 0) { mLineBottom = mLineTop + mLongLineHeight; mLinePaint.setStrokeWidth(mLineWidth); } else { mLineBottom = mLineTop + mShortLineHeight; mLinePaint.setStrokeWidth(mHalfLineWidth); } if (i % 6 == 0) { canvas.save(); canvas.rotate(i, mHalfWidth, mHalfHeight); canvas.drawLine(mLineLeft, mLineTop, mLineLeft, mLineBottom, mLinePaint); canvas.restore(); } } }