Canvas中drawxxx方法的使用

一:Canvas.drawxxx()系列方法以及Paint常见使用

1:移动坐标系

canvas.translate(width/2,height/2); //可以将坐标系从左上角移动到指定位置
cavas.scale(1,-1);//反转y坐标轴,反转之后向上为正,向下为负。

2:drawRect(float left, float top, float right, float bottom, Paint paint)

画矩形传入的是左上点和右下点的坐标。drawRect(左上x,左上y,右下x,右下y,paint);

3:drawPoint(float x, float y, Paint paint)

在画点的时候,需要paint.setStrokeWidth();不然点看不到。

(1):画多个点

 float [] pts={30,100,100,100,170,100,240,100,310,100};
private void init() {
    paint=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.parseColor("#2bb8ed"));
    paint.setStrokeWidth(50);
    paint.setStrokeCap(Paint.Cap.ROUND);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPoints(pts,paint);
//        canvas.drawPoints(pts,2,6,paint);
}
Canvas中drawxxx方法的使用_第1张图片

(2):画多个点同时偏移

 float [] pts={30,100,100,100,170,100,240,100,310,100};
    private void init() {
        paint=new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.parseColor("#2bb8ed"));
        paint.setStrokeWidth(50);
        paint.setStrokeCap(Paint.Cap.ROUND);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        canvas.drawPoints(pts,paint);
        canvas.drawPoints(pts,2,6,paint);
    }

使用的数组还是之前的数组,就是在drawPoints的参数上做了调整。该方法第二个参数表示从第几个数组元素开始绘制,由于数组的元素是两个点构成一个坐标,因此偏移两个位置,即一个点。第三个参数表示一共使用几个数组元素,在本段代码中最后将原始数组进行了截取,相当于使用了下面这个新数组进行绘制。

 float [] pts={100,100,170,100,240,100};

Canvas中drawxxx方法的使用_第2张图片

如果我们将参数调整为

canvas.drawPoints(pts,1,7,paint);

将会显示如下,虽然取了7个元素,但是最后一个元素没有配对的y坐标,无法绘制出来。


Canvas中drawxxx方法的使用_第3张图片

4:drawOval(float left, float top, float right, float bottom, @NonNull Paint paint);

前两个参数可以认为是椭圆外切矩形的左上点坐标。
接下来的两个参数可以认为是椭圆外切矩形的右下点坐标。

5:画线drawLine(float startX, float startY, float stopX, float stopY,@NonNull Paint paint)

我们通过代码画了三条线,分别设置了不同的Cap,三条线除了颜色不一样和cap不一样之外,其他的都一致。

 private void init() {
    paint=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.RED);
    paint.setStrokeWidth(50);
    paint.setStrokeCap(Paint.Cap.BUTT);

    paint1=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint1.setColor(Color.GRAY);
    paint1.setStrokeWidth(50);
    paint1.setStrokeCap(Paint.Cap.ROUND);

    paint2=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint2.setColor(Color.BLUE);
    paint2.setStrokeWidth(50);
    paint2.setStrokeCap(Paint.Cap.SQUARE);
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawLine(30,30,30,630,paint);
    canvas.drawLine(130,30,130,630,paint1);
    canvas.drawLine(230,30,230,630,paint2);
    }
Canvas中drawxxx方法的使用_第4张图片

但是从效果图中,我们看到的三条线的长度好像并不一致。从代码中我们知道我们设置的起始点y坐标是30,但是只有第一条线满足了,后面两条线不满足,长度为600,也只有第一条满足了,后面两条未满足。因为cap是指当画笔画完之后,再给任务画一个帽子,这个帽子是多出来的。

和cap类似的还有一个join

public enum Join {  
    /** 
     * The outer edges of a join meet at a sharp angle 
     */  
    MITER   (0),  
    /** 
     * The outer edges of a join meet in a circular arc. 
     */  
    ROUND   (1),  
    /** 
     * The outer edges of a join meet with a straight line 
     */  
    BEVEL   (2);  
      
    private Join(int nativeInt) {  
        this.nativeInt = nativeInt;  
    }  
    final int nativeInt;  
}
Canvas中drawxxx方法的使用_第5张图片
图片来自gcsSloop

6:drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)

圆角矩形

7:drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

扇形或者弧形或者弧线。是否填充全在于paint.setStyle(Paint.Style.);

三点钟方向为0度。

顺时针为正方向。

useCenter表示在两边是否用线连接到圆心。如果连接就是弧形,不连接就是扇形。

 private void init() {
    paint=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.RED);
    paint.setStrokeWidth(10);
    paint.setStrokeCap(Paint.Cap.BUTT);
    paint.setStyle(Paint.Style.STROKE);

    paint1=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint1.setColor(Color.GRAY);
    paint1.setStrokeWidth(50);
    paint1.setStrokeCap(Paint.Cap.ROUND);

    paint2=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint2.setColor(Color.BLUE);
    paint2.setStrokeWidth(10);
    paint2.setStrokeCap(Paint.Cap.SQUARE);
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawArc(0, 0, 200, 200, 50, 100, false, paint); 
    canvas.drawArc(0, 200, 300, 400, -360, 100, true, paint); 
    canvas.drawArc(0, 500, 400, 700, -150, 100, false, paint1); 
    canvas.drawArc(400, 500, 500, 600, -150, 100, true, paint1); 

    }
Canvas中drawxxx方法的使用_第6张图片

8:drawPath

path有两种方法,一类是直接描述路径,一类是辅助设置或计算

(1):addCircle/addOval/addArc/addRect/addRoundRect。

最后一个参数dir表示方向,有两个选项,一个是cr顺时针,一个是ccr逆时针。

lineTo/rLineTo 前者是绝对坐标。后者是相对坐标。都是画直线。
使用path画粗线的时候,比如直方图的粗线,一定要把style设置为stroke。

画线的方向就是方向。

quadTo/rQuadTo 画二次贝塞尔曲线。


Canvas中drawxxx方法的使用_第7张图片
二阶贝塞尔曲线图片来自网络

cubicTo/rCubicTo 画三次贝塞尔曲线


Canvas中drawxxx方法的使用_第8张图片
三阶贝塞尔曲线图片来自网络
Canvas中drawxxx方法的使用_第9张图片
四阶贝塞尔曲线图片来自网络
Canvas中drawxxx方法的使用_第10张图片
五阶贝塞尔曲线图片来自网络

moveTo/rMoveTo 移动到目标位置开始画起点

moveTo :移动到下一次操作的起点位置
setLastPoint 设置之前操作的最后一个点位置。这会取消之前的终点位置。如图所示:

Canvas中drawxxx方法的使用_第11张图片
图片来自gcsSloop

那么在3d旋转的时候,能不能通过setLastPoint来旋转一个点达到效果呢?
重点
arcTo 只画弧形不画扇形。forceMoveTo参数表示是否留下画笔的移动痕迹。

addArc()表示forceMoveTo=true的简化版arcTo。

close()封闭当前图形。终点到起点的连线。当画笔为fill的时候,会自动封闭。

在画心形的时候,不要抬笔,也就是不要将forceMoveTo设置为true,因为true就以为着是一个新的If true, always begin a new contour with the arc。那么在封闭的时候,只能封闭当前的contour,而不能封闭之前的contour了。

 path.arcTo(200,100,400,300,150, 210,false);
 path.arcTo(400,100,600,300,180, 210,false);
 path.lineTo(400, 442);

(2):辅助设置或计算 Path.setFillType(Path.FillType ft)


Canvas中drawxxx方法的使用_第12张图片
图片来自hencoder

参考:
gcsSloop的博客
Hencoder的博客

你可能感兴趣的:(Canvas中drawxxx方法的使用)