Canvas 画布

从前面我们已经知道了 Canvas 类可以绘出 各种形状。

这里学习一下Canvas 类的变换效果(平移,旋转等)

首先需要了解一下Canvas 画布, 我们用Canvas.DrawXXX()方法的时候并不是在一张画布上进行绘制。而是每次调用.DrawXXX()方法,都会生成一个新的画布并在上面绘制,这就类似于PS中的图层

从下面会看到解释。

一、偏移(.translate)

      即让画布平移,之后上面的绘制操作也会跟着平移

public void translate(float dx, float dy) ; //画布偏移
float dx:水平方向平移的距离,正数指向正方向(向右)平移的量,负数为向负方向(向左)平移的量
flaot dy:垂直方向平移的距离,正数指向正方向(向下)平移的量,负数为向负方向(向上)平移的量
        Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(); //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
canvas.drawRect(,,,,paint); //对画布进行平移操作
canvas.translate(,);
paint.setColor(Color.BLACK); //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
// 所以这时距屏幕左上角的距离为(100+120,100+120)
canvas.drawRect(,,,,paint);

   从下可见绿色框的是平移(100,100)后的新画布的位置,多出界面的部分不再显示

   黑色的矩形是在新的画布位置(绿色框)左上角为原点,(100,100)位置绘制的

  

  

  注意这时候,每次drawXXX 绘制的画布位置都以新的画布为准,比如我再绘制一个矩形

        Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(); //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
canvas.drawRect(,,,,paint); //对画布进行平移操作
canvas.translate(,);
paint.setColor(Color.BLACK); //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
// 所以这时距屏幕左上角的距离为(100+120,100+120)
canvas.drawRect(,,,,paint); //再绘制一个蓝色的矩形 ,看看这个矩形是以平移前的画布左上角为原点还是以平移后的画布左上角为原点
paint.setColor(Color.BLUE);
canvas.drawRect(,,,,paint);

 

  可见当画布进行转换(平移、旋转等)操作之后,往后drawXXX的时候都以新的画布位置为准  

  那么,比如我只想让第二个矩形所在的画布平移,而往后的都是以原来的画布为准,怎么办,难道还需要逆向操作,怎么平移出去的再怎么平移回来么

  其实Canvas类还有 两个方法:

canvas.save();        //把画布的状态(位置等)保存到栈中

canvas.restore();   //把栈中最顶层的画布状态取出来,并按照这个状态恢复当前的画布

 举例:

        Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(); //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
canvas.drawRect(,,,,paint);
canvas.save(); //保存当前画布状态 //对画布进行平移操作
canvas.translate(,);
paint.setColor(Color.BLACK); //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
// 所以这时距屏幕左上角的距离为(100+120,100+120)
canvas.drawRect(,,,,paint); canvas.restore(); //恢复成栈顶保存的画布状态
//再绘制一个蓝色的矩形 ,看看这个矩形是以平移前的画布左上角为原点还是以平移后的画布左上角为原点
paint.setColor(Color.BLUE);
canvas.drawRect(,,,,paint);

可以看到,红色矩形是在原始画布上绘制的,然后保存原始画布的状态,

     将画布平移(100,100) 绘制一个黑色的矩形,绘制之后将画布状态恢复到栈顶保存的状态

       这时候再绘制一个蓝色的矩形,会发现这个蓝色矩形是在原状态画布上绘制的。

二、旋转(.rotate)

public void rotate(float degrees)
public void rotate (float degrees, float px, float py) 第一个构造函数直接输入旋转的度数,正数是顺时针旋转,负数指逆时针旋转,它的旋转中心点是原点(0,0)
第二个构造函数除了度数以外,还可以指定旋转的中心点坐标(px,py)

 

        Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(); //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
canvas.drawRect(,,,,paint); //对画布进行旋转操作
canvas.rotate(); // 控制旋转的角度,顺时针
paint.setColor(Color.BLACK); //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
// 所以这时距屏幕左上角的距离为(100+120,100+120)
canvas.drawRect(,,,,paint);

 三、缩放(.scale)

public void scale (float sx, float sy)
sx : 水平缩放的程度
sy : 垂直缩放的程度 单位float, >1 表示扩大, <1 表示缩小 =1表示不变化
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(2); //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
canvas.drawRect(0,0,400,300,paint); //对画布进行缩放操作
canvas.scale(0.5f,0.5f); //缩小一半
paint.setColor(Color.BLACK); //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
// 所以这时距屏幕左上角的距离为(100+120,100+120)
canvas.drawRect(0,0,400,300,paint);

四、倾斜(.skew)

public void skew (float sx, float sy)
float sx:将画布在x方向上倾斜相应的角度,sx倾斜角度的tan值,
float sy:将画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值,

注意:倾斜角度的tan值,比如倾斜60度,tan60=根号3,小数对应1.732,那么参数就是1.732

 Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(); //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
canvas.drawRect(,,,,paint);
//对画布进行缩放操作
canvas.skew(1.732f,); //缩小一半
paint.setColor(Color.BLACK);
canvas.drawRect(,,,,paint);

  

 

自定义控件详解(三):Canvas效果变换的更多相关文章

  1. .NET DLL 保护措施详解(三)最终效果

    针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...

  2. 《Android群英传》读书笔记 (2) 第三章 控件架构与自定义控件详解 + 第四章 ListView使用技巧 + 第五章 Scroll分析

    第三章 Android控件架构与自定义控件详解 1.Android控件架构下图是UI界面架构图,每个Activity都有一个Window对象,通常是由PhoneWindow类来实现的.PhoneWin ...

  3. WindowsPhone自定义控件详解(二) - 模板类库分析

    转自:http://blog.csdn.net/mr_raptor/article/details/7251948 WindowsPhone自定义控件详解(一) - 控件类库分析 上一节主要分析了控件 ...

  4. android shape的使用详解以及常用效果(渐变色、分割线、边框、半透明阴影效果等)

    shape使用.渐变色.分割线.边框.半透明.半透明阴影效果. 首先简单了解一下shape中常见的属性.(详细介绍参看  api文档 ) 转载请注明:Rflyee_大飞: http://blog.cs ...

  5. Android 之窗口小部件详解(三)  部分转载

    原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...

  6. WebSocket安卓客户端实现详解(三)–服务端主动通知

    WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 We ...

  7. logback -- 配置详解 -- 三 -- <encoder>

    附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...

  8. python设计模式之装饰器详解(三)

    python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...

  9. Python操作redis字符串(String)详解 (三)

    # -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1.SET 命令用于设置 ...

  10. ios学习--详解IPhone动画效果类型及实现方法

    详解IPhone动画效果类型及实现方法是本文要介绍的内容,主要介绍了iphone中动画的实现方法,不多说,我们一起来看内容. 实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一 ...

随机推荐

  1. Linux中matplotlib 中文显示问题解决

    1.下载下载中文 arial unicode ms 字体到 /home 目录 2. 拷贝字体到 usr/share/fonts 下: sudo cp ~/arial\ unicode\ ms.ttf ...

  2. Git使用教程:最详细、最傻瓜、最浅显、真正手把手教!

    Git使用教程:最详细.最傻瓜.最浅显.真正手把手教! 蘇小小 Web项目聚集地 9月16日 作者 | 蘇小小 编辑 | 王久一 来源 | 慕课网 导读:因为教程详细,所以行文有些长,新手边看边操作效 ...

  3. 线程安全-002-多个线程多把锁&类锁

    一.多个对象多把锁 例子代码: package com.lhy.thread01; public class MultiThread { //static private int num = 0; / ...

  4. C#7.0--引用返回值和引用局部变量

    一.在C#7.0以上版本中,方法的返回值可以通过关键字ref指定为返回变量的引用(而不是值)给调用方,这称为引用返回值(Reference Return Value,或ref returns): 1. ...

  5. 协程及Python中的协程

    1 协程 1.1协程的概念 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程.(其实并没有说明白~) 我觉得单说协程,比较抽象,如果对线程有一定了解 ...

  6. k8s升级,HA集群1.12.0~HA集群1.13.2

    k8s升级,此次升级是1.12.0 至1.13.2 准备 # 首先升级master节点的基础组件kubeadm.kubelet.kubectl apt policy kubeadm 找到相应的版本,如 ...

  7. 一文揭秘定时任务调度框架quartz

    之前写过quartz或者引用过quartz的一些文章,有很多人给我发消息问quartz的相关问题, quartz 报错:java.lang.classNotFoundException quartz源 ...

  8. 分布式文件系统FastDFS安装教程

    前言 FastDFS(Fast Distributed File System)是一款开源轻量级分布式文件系统,本文不讲解原理和架构,只是在个人使用部署过程中耗费了好长时间和精力,遇到了很多的坑,于是 ...

  9. 深入浅出 JVM GC(3)

    # 前言 在 深入浅出 JVM GC(2) 中,我们介绍了一些 GC 算法,GC 名词,同时也留下了一个问题,就是每个 GC 收集器的具体作用.有哪些 GC 收集器呢? Serial 串行收集器(只适 ...

  10. python的类变量与实例变量以及__dict__属性

    关于Python的实例变量与类变量,先来看一段可能颠覆世界观的例子 #!/usr/bin/env python # -*- coding: utf_8 -*- # Date: 2016年10月10日 ...