Canvas---Canvas变换与操作

平移

Canvas类提供了一个translate()方法就是用来平移画布,以左上角为原点,向右为x轴正方向,向下为y轴正方向。

将画布沿着x轴和y轴的正方向都移动200像素之后,在画布上绘制一个图形:

canvas.translate(200,200);
        RectF rectF=new RectF(0,0,400,200);
        canvas.drawRect(rectF,paint);

发现,当前绘制的矩形距离屏幕的订点有一段距离。

屏幕显示与Canvas的关系

在看其他操作之前,需要知道屏幕显示和Canvas的关系如何,首先看一个例子:先在画布上绘制一个矩形,随后平移画笔,接着在相同的位置再绘制一个矩形,看一下两者是否重合:

paint.setStyle(Paint.Style.STROKE);
        RectF rectF=new RectF(0,0,400,200);
        canvas.drawRect(rectF,paint);
        canvas.translate(200,200);
        paint.setColor(Color.RED);
        canvas.drawRect(rectF,paint);

很明显的看出,两者并不重合。在这里,需要知道Canvas是一个很虚幻的概念,相当于一个透明图层(用过PS的同学应该都知道),每次Canvas画图时(即调用Draw系列函数),都会产生一个透明图层,然后在这个图层上画图,画完之后覆盖在屏幕上显示。所以第二次绘制矩形的时候,其实已经使用了一个新的画布。总结来说,有如下几点注意点:
**1、每次调用canvas.drawXXXX系列函数来绘图进,都会产生一个全新的Canvas画布。
2、如果在DrawXXX前,调用平移、旋转等函数来对Canvas进行了操作,那么这个操作是不可逆的!每次产生的画布的最新位置都是这些操作后的位置。(关于Save()、Restore()的画布可逆问题的后面再讲)
3、在Canvas与屏幕合成时,超出屏幕范围的图像是不会显示出来的。**

旋转

画布的旋转操作默认是围绕着原点来操作的,Canvas提供了一个可以指定旋转点的方法:

void rotate(float degrees)
void rotate (float degrees, float px, float py)

第一个构造函数直接输入旋转的度数,正数是顺时针旋转,负数指逆时针旋转,它的旋转中心点是原点(0,0)
第二个构造函数除了度数以外,还可以指定旋转的中心点坐标(px,py)

下面看一个简单的Canvas旋转操作:

paint.setStyle(Paint.Style.STROKE);
        RectF rectF=new RectF(0,0,400,200);
        canvas.drawRect(rectF,paint);
        canvas.rotate(45,200,200);
        paint.setColor(Color.RED);
        canvas.drawRect(rectF,paint);

缩放
下面是一个对Canvas的缩放操作:

paint.setStyle(Paint.Style.FILL);
        RectF rectF=new RectF(0,0,200,100);
        canvas.drawRect(rectF,paint);

        paint.setColor(Color.GREEN);
        canvas.scale(0.5f,1);
        canvas.drawRect(rectF,paint);

扭曲

类似于PS中的斜切效果,两个参数,分别是x轴和y轴倾斜的度数

void skew (float sx, float sy)

float sx:将画布在x方向上倾斜相应的角度,sx倾斜角度的tan值,
float sy:将画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值,

 paint.setStyle(Paint.Style.STROKE);
        RectF rectF=new RectF(0,0,400,200);
        canvas.drawRect(rectF,paint);
        paint.setColor(Color.RED);
        canvas.skew(1.732f,0);
        canvas.drawRect(rectF,paint);

裁剪画布
裁剪画布是利用Clip系列函数,通过与Rect、Path、Region取交、并、差等集合运算来获得最新的画布形状。除了调用Save、Restore函数以外,这个操作是不可逆的,一但Canvas画布被裁剪,就不能再被恢复!
Clip系列的方法有如下这些:

boolean clipPath(Path path)
boolean clipPath(Path path, Region.Op op)
boolean clipRect(Rect rect, Region.Op op)
boolean clipRect(RectF rect, Region.Op op)
boolean clipRect(int left, int top, int right, int bottom)
boolean clipRect(float left, float top, float right, float bottom)
boolean clipRect(RectF rect)
boolean clipRect(float left, float top, float right, float bottom, Region.Op op)
boolean clipRect(Rect rect)
boolean clipRegion(Region region)
boolean clipRegion(Region region, Region.Op op)

先看一个裁剪矩形的方法:

  canvas.drawColor(Color.GREEN);
        RectF rectF=new RectF(200,200,600,400);
        canvas.clipRect(rectF);
        canvas.drawColor(Color.RED);

画布的保存与恢复

Save():每次调用Save()函数,都会把当前的画布的状态进行保存,然后放入特定的栈中;
restore():每当调用Restore()函数,就会把栈中最顶层的画布状态取出来,并按照这个状态恢复当前的画布,并在这个画布上做画。

为了更好地使用上面两个函数,在上一个例子上进行修改:

 canvas.drawColor(Color.GREEN);
        canvas.save();  //保存
        RectF rectF=new RectF(200,200,600,400);
        canvas.clipRect(rectF);
        canvas.drawColor(Color.RED);
        canvas.restore();
        canvas.drawColor(Color.BLUE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLACK);
        paint.setTextSize(50);
        canvas.drawText("addas",100,100,paint);

上述例子中,画布被裁剪为一个小矩形,在本例中,使用了restore()进行了恢复,并将画布的背景色改为蓝色。

现在多次使用save()和restore()方法,来了解一下Canvas画布状态的栈的概念:

 canvas.drawColor(Color.rgb(133,133,133));
        canvas.save();
         paint.setStyle(Paint.Style.FILL);
        canvas.clipRect(new RectF(50,50,850,850));
        canvas.drawColor(Color.RED);
        canvas.save();
        canvas.clipRect(new RectF(150,150,750,750));
        canvas.drawColor(Color.GREEN);
        canvas.save();
        canvas.clipRect(new RectF(250,250,650,650));
        canvas.drawColor(Color.GRAY);
        canvas.save();
        canvas.clipRect(new RectF(450,450,600,600));
        canvas.drawColor(Color.YELLOW);

        canvas.restore();
        canvas.drawColor(Color.rgb(0,0,0));

从上述的代码中可以看出,共使用了4次save()操作,使用了一次restore()操作,可以看到最里面的那个小正方向不再是黄色的,而是黑色的,说明当前Canvas的状态为400*400的正方形。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值