博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android自定义View-------Canvas动画的误解
阅读量:5861 次
发布时间:2019-06-19

本文共 2231 字,大约阅读时间需要 7 分钟。

前言

最近在看自定义View方面的知识,遇到下面一段代码,由于对旋转后的绘图存在疑问,经过多方求证,最后弥补了操作Canvas(旋转,平移等)认知的错误,并得出正确结论:

动画操作Canvas,其实操作的是临时坐标系,对于已经绘制的图形部分无效

下面详细记录求证过程,以备同仁指正:

建议大家按照代码绘制看看,绘制对的可以留言,绘制错了也可以留言,这篇博客让你理解了吗?

/**     * 在画布的 左下角画圆,     * 中间画向右箭头 :旋转画布后再画     * 右上角画圆:画布旋转为原始方向后再画     * @param canvas     */    private void canvasTest(Canvas canvas) {        int width = 200;        int height = 200;        int radius = 10;        int centerX = radius;        int centerY = height - radius;        Paint paint = new Paint();        //画做左下角的圆        paint.setStyle(Paint.Style.FILL);        paint.setColor(Color.BLUE);        paint.setAntiAlias(true);        canvas.drawCircle(centerX, centerY, radius, paint);        // 1.-------------------------------------------------------------       canvas.save();       canvas.rotate(90, width/2, height/2);   //以画布中心为旋转点//      canvas.translate(0, -30);//      canvas.scale(1.2f, 1.2f, width/2, height/2);        paint.setColor(Color.RED);        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeWidth(4);        //左线、右线、中线, 把旋转后的当做新画布,但x, y 的坐标仍是原来方向的,但画出的图是旋转后的        //可以想象为先在原始画布上画,画好后旋转        canvas.drawLine(width/2, 0, 0, height/2, paint);        canvas.drawLine(width/2, 0, width, height/2, paint);        canvas.drawLine(width/2, 0, width/2, height, paint);        // 2.----------------------------------------------------        canvas.restore();  //如果不加这一行,那么下面的那个右上角的圆是 旋转后的画布的右上角,而非原始画布的右上角位置        //右上角画个圆        int cx2 = width - radius;        int cy2 = radius;        paint.setStyle(Paint.Style.FILL);        paint.setColor(Color.RED);        canvas.drawCircle(cx2, cy2, radius, paint);    }复制代码

上述的代码在我求证之初,我得出的图形是这样的:

既然是错误的,就不多解释了,免得误导大家。

下面是正确的绘图结果:

对比错误的和正确的绘图,不难发现三点差异:

第一:坐标系差异(这是个隐形的差异);

第二:旋转前绘制的圆的差异(旋转前绘制的圆到底该不该跟随Canvas旋转,为什么跟随旋转的是错的呢?)

第三:最后一个圆的差异(这个差异其实是因为第一个原因坐标系的差异导致的);

接下来我们就对这三个差异一一解释:

先说第二个,旋转前绘制的圆的差异?

这个问题的原因就是我在最前面所说的:旋转Canvas时,其实旋转的是临时的坐标系,只对旋转后的图形有效,对旋转前的绘图无效。

接下来说第一个差异,最后一个圆绘制在canvas.restore()后面,此时的坐标系还是旋转后的坐标系吗?

答案是NO! canvas.restore()方法和canvas.save()方法,细心的朋友可以发现,我在前面特别表示了这两个方法的位置,canvas.save()写在旋转之前,canvas.restore()方法就是将坐标系恢复到sava方法调用的地方,所以他们是成双成对出现的。

总结

动画操作Canvas,其实操作的是临时坐标系,对于已经绘制的图形部分无效。而Canvas.restore方法等于是将Canvas动画操作还原成Save时的状态

你对这个容易误解的知识点掌握了吗?

转载地址:http://rwwnx.baihongyu.com/

你可能感兴趣的文章
python标准库00 学习准备
查看>>
4.2. PHP crypt()
查看>>
Python递归函数与匿名函数
查看>>
loadrunner安装运行一步一步来(多图)
查看>>
监控工具htop的安装及使用
查看>>
Spring 任务调度 简单的,使用Schedule
查看>>
SQL 2005删除作业计划出错(DELETE语句与 REFERENCE约束"FK_subplan_job_id"冲突。)的解决...
查看>>
进老男孩的自我介绍和决心书
查看>>
Android一些问题的解决方案
查看>>
目标与绩效管理实战专家胡立
查看>>
2014手机分析图
查看>>
一元多项式相加
查看>>
commandLink/commandButton/ajax backing bean action/listener method not invoked (转)
查看>>
(一) pyhon 基础语法(数值 字符串 元组 列表 字典)
查看>>
HDOJ 1003:求一串数字中和最大的连续子串
查看>>
RedHat 5.6_x86_64 + ASM + RAW+ Oracle 10g RAC (二)
查看>>
MySQL/InnoDB的并发插入Concurrent Insert
查看>>
转两好文防丢:Debian 版本升级/降级 & Linux 应用程序失去输入焦点问题的解决...
查看>>
HDU - Pseudoforest
查看>>
Nexus杂
查看>>