这次纯API练习,比较简单,但是是为了之后的结合项目打基础的,所以也不能忽视它,下面开始:

Canvas的平移、旋转、缩放

这里还是以上次画那个青春痘的DEMO为例【http://www.cnblogs.com/webor2006/p/7341697.html】,在此基础上进行画步操作,先贴一下目前的代码及效果:

/**
* 自定义View操练----画一个形象可爱的笑脸^_^
*/
public class MyView extends View { private Paint paint;
/* 笑脸圆的坐标 */
private final PointF facePoint = new PointF(240, 400);
/* 笑脸圆的半径 */
private final int faceRadius = 200; /* 眉毛线开始坐标 */
private final PointF eyebrowStartPoint = new PointF(140, 250);
/* 眉毛线结束坐标 */
private final PointF eyebrowEndPoint = new PointF(340, 250); /* 鼻子中竖线开始坐标 */
private final PointF noseLine1StartPoint = new PointF(240, 250);
/* 鼻子中竖线结束坐标 */
private final PointF noseLine1EndPoint = new PointF(240, 500);
/* 鼻子左勾线结束坐标,其它的开始坐标为noseLine1EndPoint */
private final PointF noseLine2EndPoint = new PointF(150, 450); /* 左眼圆的坐标 */
private final PointF leftEyePoint = new PointF(170, 330);
/* 右眼圆的坐标 */
private final PointF rightEyePoint = new PointF(310, 330);
/* 眼睛圆的半径 */
private final int eyeRadius = 60; /* 嘴的圆弧外接矩形 */
//参数为left(距屏幕左边的x坐标位置)、top(距屏幕左边的x坐标位置)、right(距屏幕左边的x坐标位置)、bottom(距屏幕左边的x坐标位置)
private final RectF mouseRectF = new RectF(60, 300, 420, 550);
/* 嘴的圆弧起始角度 */
private final float startAngle = 380f;
/* 嘴的圆弧的弧度 */
private final float sweepAngle = 140f; /* 左美丽青春痘 */
private final float[] leftAcnePoints = {130, 414, 111, 442, 152, 442, 130, 470, 130, 442};
/* 左美丽青春痘 */
private final float[] rightAcnePoints = {350, 414, 331, 442, 372, 442, 350, 470, 350, 442}; /* 左朵耳相关的坐标点,用Path将其连接优化耳朵 */
private final PointF leftEarMovePoint = new PointF(65, 300);
private final PointF leftEarBezierEndPoint1 = new PointF(40, 400);
private final PointF leftEarBezierEndPoint2 = new PointF(65, 500);
private final PointF leftEarBezierControlPoint1 = new PointF(0, 336);
private final PointF leftEarBezierControlPoint2 = new PointF(0, 460);
/* 右朵耳相关的坐标点,用Path将其连接优化耳朵 */
private final PointF rightEarMovePoint = new PointF(413, 300);
private final PointF rightEarBezierEndPoint1 = new PointF(440, 400);
private final PointF rightEarBezierEndPoint2 = new PointF(413, 500);
private final PointF rightEarBezierControlPoint1 = new PointF(480, 336);
private final PointF rightEarBezierControlPoint2 = new PointF(480, 460); public MyView(Context context) {
this(context, null);
} public MyView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
} private void init() {
paint = new Paint();
//设置画笔的颜色
paint.setColor(Color.RED);
//设置抗锯齿:开启它会有些性能损耗,但是画面更加平滑~
paint.setAntiAlias(true);
//设置画笔的样式:绘制空心图形
paint.setStyle(Paint.Style.STROKE);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); //1、画个圆脸:
//参数1,2:圆心的x,y坐标
//参数3 radius:圆的半径
canvas.drawCircle(facePoint.x, facePoint.y, faceRadius, paint); //2、画一字眉:
//参数1,2:线的起始坐标点
//参数3,4:线的结束坐标点
canvas.drawLine(eyebrowStartPoint.x, eyebrowStartPoint.y, eyebrowEndPoint.x, eyebrowEndPoint.y, paint); //画一个眉毛,这里用一横线来形象的代表~~ //3、画勾鼻:
canvas.drawLine(noseLine1StartPoint.x, noseLine1StartPoint.y, noseLine1EndPoint.x, noseLine1EndPoint.y, paint); //画鼻子中竖线
canvas.drawLine(noseLine1EndPoint.x, noseLine1EndPoint.y, noseLine2EndPoint.x, noseLine2EndPoint.y, paint); //画鼻子左勾线 //4、画两眼:
canvas.drawCircle(leftEyePoint.x, leftEyePoint.y, eyeRadius, paint);//画左眼睛,用萌萌哒的正圆来形象的代表~~
canvas.drawCircle(rightEyePoint.x, rightEyePoint.y, eyeRadius, paint);//画右眼睛,用萌萌哒的正圆来形象的代表~~ //5、画嘴:
//参数1 RectF:矩形,是圆弧所在圆的外接矩形
//参数2 startAngle:弧的起始角度
//参数3 sweepAngle:弧的弧度
//参数4 useCenter: 如果为true则会以圆中心画一个弧;如果为false则只要一个弧线,没有中心点到弧的一个连线
canvas.drawArc(mouseRectF, startAngle, sweepAngle, false, paint);
//for test:看一下是不是刚好圆弧就是在外切矩形里面
//canvas.drawRect(mouseRectF, paint); //6、画美丽青春痘:
//参数1 pts: 绘制的点的坐标集合,[x0 y0 x1 y1 x2 y2 ...]
//参数2 offset: 参数1中的这么一串数字哪个表示X,哪个表示Y,则由此参数决定,也就是指定参数1中哪个点作为起始点作为横坐标,然后依次顺延
//比如:如果传0,则第一个数表示x、第二个数表示y;而如果传1则第二个数是x,第三个数是y,之后的一次顺延
//参数3 count: 需要使用集合中的几个元素
canvas.drawPoints(leftAcnePoints, 0, leftAcnePoints.length, paint);//画左美丽青春痘
canvas.drawPoints(rightAcnePoints, 0, rightAcnePoints.length, paint);//画右美丽青春痘 //7、画耳朵方案三【利用贝塞尔曲线终极优化】:
//利用path来优化耳朵,之前是一个太不真实的矩形代替滴
Path leftEarPath = new Path();
leftEarPath.moveTo(leftEarMovePoint.x, leftEarMovePoint.y);
leftEarPath.quadTo(leftEarBezierControlPoint1.x, leftEarBezierControlPoint1.y, leftEarBezierEndPoint1.x, leftEarBezierEndPoint1.y);
leftEarPath.quadTo(leftEarBezierControlPoint2.x, leftEarBezierControlPoint2.y, leftEarBezierEndPoint2.x, leftEarBezierEndPoint2.y);
canvas.drawPath(leftEarPath, paint);
Path rightEarPath = new Path();
rightEarPath.moveTo(rightEarMovePoint.x, rightEarMovePoint.y);
rightEarPath.quadTo(rightEarBezierControlPoint1.x, rightEarBezierControlPoint1.y, rightEarBezierEndPoint1.x, rightEarBezierEndPoint1.y);
rightEarPath.quadTo(rightEarBezierControlPoint2.x, rightEarBezierControlPoint2.y, rightEarBezierEndPoint2.x, rightEarBezierEndPoint2.y);
canvas.drawPath(rightEarPath, paint);
}
}

记住这张笑脸的位置,下面的实验会对其进行位置变换,可以有个感观上的认识。

①、Canvas的平移:

先来贴一下官网平移API的介绍:

下面将画布的x坐标平移200,看下效果:

编译运行:

效果比较简单,但是需要用坐标系的概念去理解它,如下:

②、Canvas的旋转:

先将①实验的代码还原,基于正脸进行旋转实验,先上官网apI介绍:

下面实验下,将画片旋转-45度:

编译运行:

如何理解?还得去分析坐标系,如图:

③、Canvas的缩放:

继续先将②的测试代码还原,先看一下官方API的介绍:

下面看代码:

编译运行:

由于比较好理解,就不多解释,不过这里有个注意点:

推荐写法是在做上面几个画布动作之前先调用save(),等操作处理完之后,再调用restore方法,具体如下:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); canvas.save();
//平移画布
// canvas.translate(200, 0);
//旋转画布
// canvas.rotate(-45);
//缩放画布
canvas.scale(0.2f, 0.2f); //1、画个圆脸:
//参数1,2:圆心的x,y坐标
//参数3 radius:圆的半径
canvas.drawCircle(facePoint.x, facePoint.y, faceRadius, paint); //2、画一字眉:
//参数1,2:线的起始坐标点
//参数3,4:线的结束坐标点
canvas.drawLine(eyebrowStartPoint.x, eyebrowStartPoint.y, eyebrowEndPoint.x, eyebrowEndPoint.y, paint); //画一个眉毛,这里用一横线来形象的代表~~ //3、画勾鼻:
canvas.drawLine(noseLine1StartPoint.x, noseLine1StartPoint.y, noseLine1EndPoint.x, noseLine1EndPoint.y, paint); //画鼻子中竖线
canvas.drawLine(noseLine1EndPoint.x, noseLine1EndPoint.y, noseLine2EndPoint.x, noseLine2EndPoint.y, paint); //画鼻子左勾线 //4、画两眼:
canvas.drawCircle(leftEyePoint.x, leftEyePoint.y, eyeRadius, paint);//画左眼睛,用萌萌哒的正圆来形象的代表~~
canvas.drawCircle(rightEyePoint.x, rightEyePoint.y, eyeRadius, paint);//画右眼睛,用萌萌哒的正圆来形象的代表~~ //5、画嘴:
//参数1 RectF:矩形,是圆弧所在圆的外接矩形
//参数2 startAngle:弧的起始角度
//参数3 sweepAngle:弧的弧度
//参数4 useCenter: 如果为true则会以圆中心画一个弧;如果为false则只要一个弧线,没有中心点到弧的一个连线
canvas.drawArc(mouseRectF, startAngle, sweepAngle, false, paint);
//for test:看一下是不是刚好圆弧就是在外切矩形里面
//canvas.drawRect(mouseRectF, paint); //6、画美丽青春痘:
//参数1 pts: 绘制的点的坐标集合,[x0 y0 x1 y1 x2 y2 ...]
//参数2 offset: 参数1中的这么一串数字哪个表示X,哪个表示Y,则由此参数决定,也就是指定参数1中哪个点作为起始点作为横坐标,然后依次顺延
//比如:如果传0,则第一个数表示x、第二个数表示y;而如果传1则第二个数是x,第三个数是y,之后的一次顺延
//参数3 count: 需要使用集合中的几个元素
canvas.drawPoints(leftAcnePoints, 0, leftAcnePoints.length, paint);//画左美丽青春痘
canvas.drawPoints(rightAcnePoints, 0, rightAcnePoints.length, paint);//画右美丽青春痘 //7、画耳朵方案三【利用贝塞尔曲线终极优化】:
//利用path来优化耳朵,之前是一个太不真实的矩形代替滴
Path leftEarPath = new Path();
leftEarPath.moveTo(leftEarMovePoint.x, leftEarMovePoint.y);
leftEarPath.quadTo(leftEarBezierControlPoint1.x, leftEarBezierControlPoint1.y, leftEarBezierEndPoint1.x, leftEarBezierEndPoint1.y);
leftEarPath.quadTo(leftEarBezierControlPoint2.x, leftEarBezierControlPoint2.y, leftEarBezierEndPoint2.x, leftEarBezierEndPoint2.y);
canvas.drawPath(leftEarPath, paint);
Path rightEarPath = new Path();
rightEarPath.moveTo(rightEarMovePoint.x, rightEarMovePoint.y);
rightEarPath.quadTo(rightEarBezierControlPoint1.x, rightEarBezierControlPoint1.y, rightEarBezierEndPoint1.x, rightEarBezierEndPoint1.y);
rightEarPath.quadTo(rightEarBezierControlPoint2.x, rightEarBezierControlPoint2.y, rightEarBezierEndPoint2.x, rightEarBezierEndPoint2.y);
canvas.drawPath(rightEarPath, paint); canvas.restore();
}

绘制文本

这里用一个新的工程来实验,其代码结构比较简单,一个Activity,一个自定义的view:

①、绘制文本:

先看一下官方API:

比较好理解:

编译运行:

但是字体有点小,于是乎看②

②、设置文本大小:

太小儿科上,直接上代码,不解释:

编译运行:

③、设置文本粗体:

④、设置文本下划线:

编译运行:

⑤、设置文本中划线:

⑥、设置文本对齐方式:

这个有必要解释一下,先看下官网API:

其中有三种对齐方式:

下面先上代码看结果:

居中对齐:

编译运行:

左对齐:

编译运行:

右对齐:

编译运行:

呃~~发现问题木有,居然向左对齐文字在屏幕偏右,而向右对齐文字在屏幕偏右,这是为啥呢,下面解释一下:

而对齐方式就是依据上面的基准点来的,规则如下:

居中对齐,则是基准点位于文本的中间;

居右对齐,则是基准点位于文本的右边;

居左对齐,则是基准点位于文本的左边;

⑦、设置文本x方向缩放:

先看一下官网API:

下面看下代码效果:

编译运行:

也就是X横向扩宽了2倍,但是木有对Y进行扩宽的api。

Canvas对画布及文字控制基础API学习的更多相关文章

  1. HTML5 Canvas(画布)实战编程初级篇:基本介绍和基础画布元素

    欢迎大家阅读HTML5 Canvas(画布)实战编程初级篇系列,在这个系列中,我们将介绍最简单的HTML5画布编程.包括: 画布元素 绘制直线 绘制曲线 绘制路径 绘制图形 绘制颜色,渐变和图案 绘制 ...

  2. 安卓自定义View进阶-Canvas之画布操作 转载

    安卓自定义View进阶-Canvas之画布操作 转载 https://www.gcssloop.com/customview/Canvas_Convert 本来想把画布操作放到后面部分的,但是发现很多 ...

  3. 服务器编程入门(4)Linux网络编程基础API

      问题聚焦:     这节介绍的不仅是网络编程的几个API     更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系.     这节主要介绍三个方面的内容:套接字( ...

  4. Linux 高性能服务器编程——Linux网络编程基础API

    问题聚焦:     这节介绍的不仅是网络编程的几个API     更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系.     这节主要介绍三个方面的内容:套接字(so ...

  5. Linux网络编程基础API

    第5章 Linux网络编程基础API 探讨Linux网络编程基础API与内核中TCP/IP协议族之间的关系,并未后续章节提供编程基础.从3个方面讨论Linux网络API. socket地址API.so ...

  6. java多线程基础API

    本次内容主要讲认识Java中的多线程.线程的启动与中止.yield()和join.线程优先级和守护线程. 1.Java程序天生就是多线程的 一个Java程序从main()方法开始执行,然后按照既定的代 ...

  7. Linux高性能server编程——Linux网络基础API及应用

     Linux网络编程基础API 具体介绍了socket地址意义极其API,在介绍数据读写API部分引入一个有关带外数据发送和接收的程序,最后还介绍了其它一些辅助API. socket地址API 主 ...

  8. Android BLE与终端通信(一)——Android Bluetooth基础API以及简单使用获取本地蓝牙名称地址

    Android BLE与终端通信(一)--Android Bluetooth基础API以及简单使用获取本地蓝牙名称地址 Hello,工作需要,也必须开始向BLE方向学习了,公司的核心技术就是BLE终端 ...

  9. canvas转图片中的文字自动换行

    概述 最近项目用到了canvas转图片,但是由于canvas对文字排版的支持非常弱,一般我们在canvas上画不同排版的文字(比如竖排文字)都是利用js计算横纵坐标,然后一个字一个字地画出来,今天无意 ...

随机推荐

  1. MATLAB 2016b + CUDA10.1 +MatConvNet beta25 安装踩坑记

    最近因为目标跟踪实验需要得安装MatConvNet,由于已经是2019年了大家的软件版本肯定不可能是像官网要求的那样,所以安装自然而然就会碰到很多问题.在这一过程中我参考了网上很多博主的经验,有些确实 ...

  2. 【AMAD】sorl-thumbnail -- Django缩略图

    动机 简介 个人评分 动机 生成缩略图是一个烦人的工作. 简介 sorl-thumbnail1的特性包括: 支持不同的storage 实现缩略图的引擎是可以切换的:Pillow, ImageMagic ...

  3. 建立自己的数据类型——C结构体归纳

    一.建立结构体类型 1.申明结构体类型 struct 结构体名 { 成员表列(类型名 成员名:); }: 例如: struct Person { char name; int age; char se ...

  4. 最新 人民网java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.人民网等10家互联网公司的校招Offer,因为某些自身原因最终选择了人民网.6.7月主要是做系统复习.项目复盘.LeetCo ...

  5. 最新 猎豹移动java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.猎豹移动等10家互联网公司的校招Offer,因为某些自身原因最终选择了猎豹移动.6.7月主要是做系统复习.项目复盘.Leet ...

  6. springBoot--组合注解RestController,GetMapping,PostMapping

    一.RestController @RestController 是@Controller和@ResponseBody的缩写 二.@getMapping和PostMapping @GetMapping ...

  7. Fourier serie

    你眼中看似落叶纷飞变化无常的世界,实际只是躺在上帝怀中一份早已谱好的乐章. 时域和频域就像观察一个物体一样,一个是主视图的,一个是侧视图. 1.在有限区间上由任意图形定义的任意函数都可以表示为单纯的正 ...

  8. OLTP和 OLAP区别

    联机事务处理OLTP(on-line transaction processing) 主要是执行基本日常的事务处理,比如数据库记录的增删查改.比如在银行的一笔交易记录,就是一个典型的事务. OLTP的 ...

  9. springboot+JPA 整合redis

    1.导入redis依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifact ...

  10. base64转码java版

    package com.net.util; import java.io.FileInputStream; import java.io.FileOutputStream; import java.i ...