Android 中 Canvas的功能

Android 中 Canvas的功能

一. 如何在一屏幕上绘图

三个概念:

  1. 需要有画布Canvas
  2. 需要有笔Paint
  3. 需要有坐标系,画笔默认是在左上角(0,0)位置绘制的。我们可以通过移动画布坐标原点的形式,实现在不同位置绘制。
1. 移动坐标原点
  简单绘制一个图

我们将画笔Canvas.translate(100,400)移动之后再进行绘制,这时画布的原点已经变化了。

2. 视图坐标系

理论上 Canvas 这张纸是没有边界的,但是我们的手机屏幕是有界的。我们可以理解为我们透过一个方形的洞(手机屏幕)看一张巨画(Canvas)。

而这里我们就又存在一个问题了,因为刚才的移动,我们是移动的原点,也就是说我们的画布是静止不动的,只是落笔点一直在变动,这就导致我们绘制的图对于用户来说是看不全的,所以我们需要进行移动 方形的洞 来查看这幅画。

举个例子,我们要查看最开始所说的画,可以通过移动 Screen框来查看这幅画,而这里又出现了一个坐标系,这一坐标系则为 视图坐标系,通过 scrollerToscrollerBy 进行移动该Screen框,正数则往正半轴,负数则往负半轴。

3. 小结

自定义控件中存在两个坐标系需要明确,用一句话总结如下:

  1. 绘图坐标系:决定我们的绘制的坐标
  2. 视图坐标系:决定我们所看到的画布范围

二、Canvas的剪刀手API

Canvas 中以 clip开头 的公有方法,用于裁剪画布的内容。裁剪之后画布之外将无法绘制, 我们抽取比较好玩的参数类型为Path的方法来分享,其余的都可以一一映射进来。

1、clipPath裁剪任意形状画布

public boolean clipPath(@NonNull Path path)

描述: 只留下 path内 的画布区域,而处于path范围之外的则不显示。

举个例子: 我们先准备好一个心形的路径Path,然后调用 clipPath 从画布中将此路径内的区域 “裁剪” 下来,最后为了我们观察,使用drawColor “染”上酒红色。

// 第一步:创建 心形路径 mPath
....省略,具体请移步demo(我会贴在末尾的)

// 第二步:从画布 canvas 裁剪下心形路径之内的区域
canvas.clipPath(mPath);

// 第三步:涂酒红色
canvas.drawColor(mBgColor);

【这个有一个网上的】 自带美感的贝塞尔曲线原理与实战

画心型路径基本是使用贝塞尔曲线的( 路径关系可以参考这个画心),路径关系如文章所示本章仅讲解和绘制相关的知识。

效果如图所示:

代码如下:

/**
 * 参考链接:https://blog.csdn.net/BigBoySunshine/article/details/53898806
 */
public class HartView extends View {
   

    public HartView(Context context) {
   
        super(context);
        init();
    }


    public HartView(Context context, @Nullable AttributeSet attrs) {
   
        super(context, attrs);
        init();
    }

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

    private void init() {
   
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);

    }

    private Paint mPaint = new Paint();
    private Path mPath = new Path();


    @Override
    protected void onDraw(Canvas canvas) {
   


        int mWidth = getWidth();
        int mHeight = getHeight();

        for (int i = 0 + 180; i < 361 + 180; i++) {
   

            double sit = i * 2 * Math.PI / 360d;

            double x = 20 * 16 * Math.pow(Math.sin(sit), 3);
            double y = 20 * (13 * Math.cos(sit) - 5 * Math.cos(2 * sit) - 2 * Math.cos(3 * sit) - Math.cos(4 * sit));
            if (i == 180) {
   
                mPath.moveTo(mWidth / 2 + (float) (x), mHeight / 2 - (float) (y));scrcpy
            }
            mPath.lineTo(mWidth / 2 + (float) (x), mHeight / 2 - (float) (y));

            if (canvas != null)
                canvas.drawPath(mPath, mPaint);
        }

    }
}
/**
 * 参考链接:https://blog.csdn.net/BigBoySunshine/article/details/53898806
 */
public class OutsideHartView extends View {
   

    public OutsideHartView(Context context) {
   
        super(context);
        init();
    }


    public OutsideHartView(Context context, @Nullable AttributeSet attrs) {
   
        super(context, attrs);
        init();
    }

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

    private void init() {
   
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);

    }

    private Paint mPaint = new Paint();
    private Path mPath = new Path();


    @Override
    protected void onDraw(Canvas canvas) {
   


        int mWidth = getWidth();
        int mHeight = getHeight();

        for (int i = 0 + 180; i < 361 + 180; i++) {
   

            double sit = i * 2 * Math.PI / 360d;

            double x = 20 * 16 * Math.pow(Math.sin(sit), 3);
            double y = 20 * (13 * Math.cos(sit) - 5 * Math.cos(2 * sit) - 2 * Math.cos(3 * sit) - Math.cos(4 * sit));
            if (i == 180) {
   
                mPath.moveTo(mWidth / 2 + (float) (x), mHeight / 2 - (float) (y));
            }
            mPath.lineTo(mWidth / 2 + (float) (x), mHeight / 2 - (float) (y));
 
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   
            canvas.clipOutPath(mPath);
        }

        canvas.drawColor(getContext().getResources().getColor(R.color.color_cd6155));
    }
2. clipRect裁剪矩形
public 
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值