关闭

[置顶] 关于canvas画布的操作,看这一篇就足够了!

标签: canvas平移旋转缩放
1233人阅读 评论(1) 收藏 举报
分类:

canvas

canvas是Android中自定义绘图中特别重要的一部分,如果你想画出想要的图形,canvas操作能帮你轻松许多。

canvas.save()和canvas.restore() 

这两个方法是最先应该了解的,save方法是将现在的画布状态保存,restore方法是将画布的状态退回到上个画布的状态,所以当我们画一些小的需要画布操作的图形的时候,先save再restore,然后在两个方法中间写上对画布的操作。

准备工作:

新建java文件MyView,定义画笔,做一些简单的初始化
private Paint mPaint;


    public MyView(Context context) {
        super(context);
        initSomeThing();
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initSomeThing();
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initSomeThing();
    }

private void initSomeThing() {
        mPaint = new Paint();
        initPaint(mPaint);
    }

    private void initPaint(Paint paint) {
        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.rgb(0x00, 0x00, 0x00));
    }

平移

先画一个圆,再按照步骤平移画布画一个一样的圆
canvas.drawCircle(100, 100, 100, mPaint);
canvas.save();
canvas.translate((float) 141.42135623731, (float) 141.42135623731);
mPaint.setColor(Color.rgb(0x91, 0xbe, 0xf0));
canvas.drawCircle(100, 100, 100, mPaint);
mPaint.setColor(Color.BLACK);
canvas.restore();

运行一下,效果如下:


同样是画两个一样的圆,结果却出现这种情况,原因是画布进行操作的时候,对应的坐标轴也跟着改变,其实我更加喜欢理解的是,我们操作的坐标轴。
canvas.translate这个方法里面的两个参数分别是向XY平移的距离,这个很简单就不赘述了

缩放

先做准备工作,把画布平移到平移到屏幕中间,画一个坐标轴,然后画一个方便比较的矩形
mPaint.setStrokeWidth(10);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);

        canvas.save();

        canvas.translate(getWidth() / 2, getHeight() / 2);
        canvas.drawLine(-550, 0, 550, 0, mPaint);
        canvas.drawLine(0, -800, 0, 800, mPaint);


        canvas.restore();
        mPaint.setStrokeWidth(0);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.FILL);

//X中心轴是Y轴   Y中心轴是X轴

//        [-∞, -1)	        先根据缩放中心放大n倍,再根据中心轴进行翻转
//        -1	            根据缩放中心轴进行翻转
//        (-1, 0)	        先根据缩放中心缩小到n,再根据中心轴进行翻转
//        0	                不会显示,若sx为0,则宽度为0,不会显示,sy同理
//        (0, 1)	        根据缩放中心缩小到n
//        1	                没有变化
//        (1, +∞)	        根据缩放中心放大n倍


        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);


        RectF rectF = new RectF(0, -300, 300, 0);
        canvas.drawRect(rectF, mPaint);
        //缩放
        canvas.scale(0.5f, 0.5f);

        mPaint.setColor(Color.BLUE);
        canvas.drawRect(rectF, mPaint);
        mPaint.setColor(Color.BLACK);

        canvas.restore();

        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);

运行效果如下:



可以看到蓝色的矩形就是XY两个方向都缩小一半的后的矩形
缩放这个方法里面的参数范围如下
        [-∞, -1)          先根据缩放中心放大n倍,再根据中心轴进行翻转
        -1               根据缩放中心轴进行翻转
       (-1, 0)          先根据缩放中心缩小到n,再根据中心轴进行翻转
        0                    不会显示,若sx为0,则宽度为0,不会显示,sy同理
        (0, 1)           根据缩放中心缩小到n
        1                    没有变化
        (1, +∞)          根据缩放中心放大n倍
上面也有写

缩放还有一个是四参的方法,后两个是旋转中心的点的坐标,个人感觉,这种不好记得操作其实可以分成两步,先把画布平移到旋转中心,然后在用上面的方法旋转效果是一样的,还好理解。不过我还是写了这个
 mPaint.setStrokeWidth(10);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.GREEN);

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);

        canvas.scale(0.5f, 0.5f, 150, 0);
        RectF rectF = new RectF(0, -300, 300, 0);
        canvas.drawRect(rectF, mPaint);

        canvas.restore();

        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);

运行效果如下:


绿色矩形就是新画出的矩形

旋转

 mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(15);
        mPaint.setColor(Color.GRAY);

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);
        canvas.rotate(45);
        //区域是距离页面左上右下    所以不是之前说的对边两个点,X2要>X1 ,Y2要>Y1   0,0,400,-400   不符合就画不出矩形
        RectF rectF = new RectF(0, -300, 300, 0);
        canvas.drawRect(rectF , mPaint);

        canvas.restore();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(0);
        mPaint.setColor(Color.BLACK);

需要注意的是,旋转里面填的那个参数是旋转角度,不是旋转的弧度,是360度那个角度不是2π那个角度,
还有就是正方向是顺时针,填负数就是逆时针旋转。

运行效果如下:


还有一个三参的方法,和缩放一样,个人建议还是先平移再旋转吧,懒得写了

对了,缩放还有一个比较有意思的玩法,先新建一个类,直接贴代码

public class ViewScaleFun extends View {

    private Paint mPaint;

    public ViewScaleFun(Context context) {
        super(context);
        initPaint();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
    }

    public ViewScaleFun(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public ViewScaleFun(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();

        canvas.translate(getWidth() / 2, getHeight() / 2);

        RectF rectF = new RectF(-500, -500, 500, 500);

        for (int i = 0; i < 30; i++) {
            canvas.scale(0.9f, 0.9f);
            canvas.drawRect(rectF, mPaint);
        }


        canvas.restore();

    }
}

运行结果如下:



哈哈  炫不酷炫酷   想不想学  







3
0
查看评论

JavaScript之Canvas画布

HTML5有个强大的功能,就是利用canvas进行画图。
  • h15882065951
  • h15882065951
  • 2017-04-18 23:10
  • 2544

H5的canvas画布使用

H5的canvas canvas画布 canvas上绘制图形 canvas给绘制的图形设置样式 canvas中绘制图像 canvas中的变形 canvas标签
  • mutouafangzi
  • mutouafangzi
  • 2017-08-14 22:46
  • 1090

canvas学习笔记(一)——关于css设置canvas画布大小的问题

canvas的绘制会是画布大小为准的。canvas的默认画布大小为300×150。通常,我们可能想要改变画布的大小,以下是大家最容易想到的方法://方法一:内联样式 <canvas style="width:450px;height:300px;"><...
  • csm0912
  • csm0912
  • 2016-10-29 11:48
  • 5758

html5 离屏canvas 的应用

离屏canvas在大多数的情况下是应用到html5 游戏中,但是最近接触到的一个项目是运用到绘制大量的图形上。 譬如有以下的需求,在一个固定的背景图上面绘制一个动态的时间。拿到这个需求,大部分搞过html5 开发的坑定知道具体的步骤怎么做,下面我简单说一下: 1、先绘制背景。 2、将时间格式化绘制到...
  • u012251421
  • u012251421
  • 2015-07-27 15:20
  • 1996

HTML5 canvas画布(一)

HTML5中canvas元素用于在网页上绘制图形。Canvas的特点 Canvas画布是一个矩形区域,可以控制其每一个像素 Canvas使用JavaScript来控制画图 Canvas具有直线、矩形、圆以及添加图像的方法 Canvas标签的使用下面的代码是使用canvas画面绘制一个200*200红...
  • anda0109
  • anda0109
  • 2016-06-18 22:10
  • 2059

html5 canvas画布居中

今天写一个demo的时候想把canvas的画布居中,一开始代码是这样的: 如图,设置了canvas的margin:0 auto;可是显示效果并不居中,如下图: 只有黑色的边框,怎么解决呢? 给canvas一个div,让div包裹canvas,设置div的宽度,并设置div的margin:0 ...
  • qq_21577869
  • qq_21577869
  • 2016-03-23 17:50
  • 9893

html5 canvas清空画布方法

总结以下三种清空canvas画布的方式: 1. 最简单的方法:由于canvas每当高度或宽度被重设时,画布内容就会被清空,因此可以用以下方法清空: [javascript] view plain copy func...
  • Inuyasha1121
  • Inuyasha1121
  • 2016-12-29 11:31
  • 9733

Canvas清空当前画布方法

Canvas想要清空当前画布的方法很简单 使用 obj.clearRect(x,y,width,height); 四个参数意思是想要清空哪个坐标点,宽高多少的画布面积; Canvas时钟demo Canvas倒计时demo *************...
  • itSeven7
  • itSeven7
  • 2017-04-20 15:00
  • 2721

讲一讲 Canvas 究竟是个啥

HTML5 的标准已经出来好久了,但是似乎其中的 Canvas 现在并没有在太多的地方用到。一个很重要的原因是,Canvas 的标准还没有完全确定,不适合大规模用在生产环境。但是,Canvas 的优点也是很明显的,例如在绘制含有大量元素的图表的时候,SVG 往往因为性能问题而无法胜任,例如我见过的一...
  • goulei2010
  • goulei2010
  • 2016-12-19 17:55
  • 603

UGUI 之 Canvas布局层级关系(一)

一、用过NGUI的人们都知道,各种NGUI的sprite之间是可以有dept来进行分层管理,以便处理层级间的关系,而在unity4.6开始的UGUI中,这是通过Canvas来设置深度关系的 我在开发中设计了三个Canvas,来处理不同的UI消息相应类型 StaticCanvas TouchOrMo...
  • bianchengxiaosheng
  • bianchengxiaosheng
  • 2015-04-12 17:02
  • 28354
    个人资料
    • 访问:28616次
    • 积分:1247
    • 等级:
    • 排名:千里之外
    • 原创:83篇
    • 转载:1篇
    • 译文:0篇
    • 评论:18条
    最新评论