【Android自定义View】绘图之Canvas篇(五)

博客围绕Android自定义View的画布展开,介绍了画布的控制方法,包括平移、旋转、缩放、斜切、裁剪等操作,还提到了画布状态的保存与回复,通过栈来实现,符合后进先出逻辑。

前言

Canvas就是我们常说的画布,之前说的所有画图操作,都是作用于Canvas之上。

Canvas主要有以下控制方法,这些方法都是作用于Canvas整体

translate 平移

我们先绘制一个矩形,平移之后,再次绘制

        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
        //平移
        canvas.translate(100, 100);
        paint.setColor(Color.RED);
        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
复制代码

可以看到,2个矩形并没有重叠

rotate 旋转

还是之前的矩形,为了方便理解,加了2条辅助线

        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
        canvas.drawLine(0, 0, 1000, 1000, paint);
        //旋转
        canvas.rotate(30);
        paint.setColor(Color.RED);
        canvas.drawLine(0, 0, 1000, 1000, paint);
        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
复制代码

可以看到,默认的旋转点是(0,0),当然我们也可以指定原点 rotate(float degrees, float px, float py)

        for (int i = 0; i < 6; i++) {
            canvas.rotate(360 / 6, 500, 1000);
            canvas.drawLine(500, 500, 500, 1000, paint);
        }
复制代码

其实是先平移,在旋转,再平移回去,源码如下

    public final void rotate(float degrees, float px, float py) {
        if (degrees == 0.0f) return;
        translate(px, py);
        rotate(degrees);
        translate(-px, -py);
    }
复制代码

scale 缩放
        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
       //缩放
        canvas.scale(0.5f, 0.5f);
        paint.setColor(Color.RED);
        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
复制代码

skew 斜切
        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
       //缩放
        canvas.skew(0, 0.5f);
        paint.setColor(Color.RED);
        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
复制代码

clip系列

clipRect(Rect rect) clipRect(RectF rect) clipRect(float left, float top, float right, float bottom) clipPath(Path path)

裁剪之后,canvas其他区域会被裁剪掉,只有区域内画的才可见

        canvas.drawRect(new Rect(500, 500, 1000, 1000), paint);
        canvas.clipRect(new Rect(500, 500, 600, 600));
        canvas.drawColor(Color.RED);
        canvas.drawCircle(500, 500, 50, paint);
复制代码

save 保存与restore 回复

之前的所有操作对于canvas 都是不可逆的,比如我们做了许多操作之后,希望将canvas的状态保存时,就要用到save。调用save方法时,会保存当前canvas状态,将其放到特定的栈中;调用restore方法时,再从栈中取出。

来看个例子,

        canvas.drawRect(new Rect(0, 0, 1000, 1000), paint);

        canvas.clipRect(new Rect(100, 100, 900, 900));
        canvas.drawColor(Color.RED);
        canvas.save();
        canvas.clipRect(new Rect(200, 200, 800, 800));
        canvas.drawColor(Color.GREEN);
        canvas.save();
        canvas.clipRect(new Rect(300, 300, 700, 700));
        canvas.drawColor(Color.YELLOW);
        canvas.save();
复制代码

当我们调用2次 restore

        canvas.restore();
        canvas.restore();
        canvas.drawColor(Color.MAGENTA);
复制代码

原先绿色部分被填充为紫红色,符合栈后进先出的逻辑。

转载于:https://juejin.im/post/5cf0e367e51d4510a732805f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值