canvas教程

Canvas之translate、scale、rotate、skew方法讲解!,canvasskew(2)

字号+ 作者:H5之家 来源:H5之家 2017-06-16 12:00 我要评论( )

接下来看刻度线的绘制,根据厘米可以计算出中间的数,根据厘米占用屏幕宽度和所占数可以计算出每一所占屏幕宽度: mLineInterval = (mTotalWidth - 2 * mDividRuleLeftMargin - 2 * mFirstLineMargin)/ (DEFAULT_CO

接下来看刻度线的绘制,根据厘米可以计算出中间的格数,根据厘米占用屏幕宽度和所占格数可以计算出每一格所占屏幕宽度:

mLineInterval = (mTotalWidth - 2 * mDividRuleLeftMargin - 2 * mFirstLineMargin) / (DEFAULT_COUNT * 10 - 1);

有了每一格所占宽度,我们只需要在绘制刻度线的时候不断将画布右移对应宽度即可:

/** * 绘制刻度线 * @param canvas */ private void drawLines(Canvas canvas) { canvas.save(); canvas.translate(mLineStartX, 0); int top = mMaxLineTop; for (int i = 0; i <= DEFAULT_COUNT * 10; i++) { if (i % 10 == 0) { top = mMaxLineTop; } else if (i % 5 == 0) { top = mMiddleLineTop; } else { top = mMinLineTop; } canvas.drawLine(0, mRuleBottom, 0, top, mLinePaint); canvas.translate(mLineInterval, 0); } canvas.restore(); }由于刻度尺上分三种长短的刻度线,我们也做对应处理,10的整数倍的刻度线最长,5的整数倍的刻度线中等长度,其余较短;

此时绘制出的刻度尺效果为:


此时刻度尺的基本样子就出来了,对应文字大家有兴趣可以自己加上;

俗话说,条条大路通罗马,我们除了使用canvas.translate ,还能不能使用别的方式进行实现呢,答案当然是可以,比如在绘制的时候根据for循环里的 i 值也可以直接计算出每一根刻度线的位置,然后直接进行绘制,相比之下,这两种方式的优劣大家也可以自行比较一下,好了,canvas.translate() 就说这么多;


二、canvas.scale( ) - 画布的缩放:

关于scale,android 提供了以下两个接口:

/** * Preconcat the current matrix with the specified scale. * * @param sx The amount to scale in X * @param sy The amount to scale in Y */ public native void scale(float sx, float sy); /** * Preconcat the current matrix with the specified scale. * * @param sx The amount to scale in X * @param sy The amount to scale in Y * @param px The x-coord for the pivot point (unchanged by the scale) * @param py The y-coord for the pivot point (unchanged by the scale) */ public final void scale(float sx, float sy, float px, float py) { translate(px, py); scale(sx, sy); translate(-px, -py); }我们先看下scale(float sx , float sy),我们还是以上面的正方形作为栗子,调用canvas.scale(float sx , float sy)之后看下效果; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLUE); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); canvas.scale(0.5f, 0.5f); mPaint.setColor(Color.YELLOW); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); }我们将画布在x,y方向上均缩放为 0.5 倍,使用默认基准点(原点 0,0),效果如下:


效果就相当于用个钉子钉在(0,0)处,然后把矩形的x,y缩放为一半,我们再来看看第二个接口scale(float sx , float sy, float px,float py):

前两个参数为将画布在x、y方向上缩放的倍数,而px和py 分别为缩放的基准点,从源码上可以非常清楚的看出和scale(float sx , float sy)的差别:

translate(px, py); scale(sx, sy); translate(-px, -py);即先将画布平移px,py,然后scale,scale结束之后再将画布平移回原基准点;

我们再在之前的基础上绘制一个同样的矩形,x , y 均缩放为 0.5 倍,缩放中心为矩形的中心:

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLUE); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); // 保存画布状态 canvas.save(); canvas.scale(0.5f, 0.5f); mPaint.setColor(Color.YELLOW); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); // 画布状态回滚 canvas.restore(); canvas.scale(0.5f, 0.5f, 200, 200); mPaint.setColor(Color.BLACK); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint); }

一起来看下效果:


效果就相当于用个钉子钉在矩形的中心,然后进行缩放;

根据上面android 的实现,我们其实可以使用以下代码实现同样的效果:

// 先将画布平移到矩形的中心 canvas.translate(200, 200); // 将画布进行缩放 canvas.scale(0.5f, 0.5f); // 将画布移回原基准点 canvas.translate(-200, -200); mPaint.setColor(Color.BLACK); canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);

到此为止,我们也就了解了对画布的缩放,基于canvas.scale(),我们一起完成一个小例子:


上面是网络上找的一张让人产生视觉误差的静态图,我们模拟绘制出上面的效果;

思路非常的简单:

1. 绘制一个和屏幕等宽的正方形;

2. 将画布以正方形中心为基准点进行缩放;

3. 在缩放的过程中绘制原正方形;

注:每次绘制都得使用canvas.save()  和 canvas.restore()进行画布的锁定和回滚,以免除对后面绘制的影响(后面会单独讲)

 

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

相关文章
  • canvas-vue

    canvas-vue

    2017-06-16 12:00

  • 如何使用HTML5 Canvas动态的绘制拓扑图

    如何使用HTML5 Canvas动态的绘制拓扑图

    2017-06-16 11:00

  • Canvas 绘图怎么旋转图片,不是画布旋转?

    Canvas 绘图怎么旋转图片,不是画布旋转?

    2017-06-16 10:03

  • HTML5 Canvas基本线条绘制的实例教程,html5canvas

    HTML5 Canvas基本线条绘制的实例教程,html5canvas

    2017-06-16 10:00

网友点评