自定义控件详解(三):Canvas效果变换

简介: Canvas 画布从前面我们已经知道了 Canvas 类可以绘出 各种形状。这里学习一下Canvas 类的变换效果(平移,旋转等) 首先需要了解一下Canvas 画布, 我们用Canvas.DrawXXX()方法的时候并不是在一张画布上进行绘制。

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(2);

        //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
        canvas.drawRect(100,100,400,300,paint);

        //对画布进行平移操作
        canvas.translate(120,120);
        paint.setColor(Color.BLACK);

        //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
        // 所以这时距屏幕左上角的距离为(100+120,100+120)
        canvas.drawRect(100,100,400,300,paint);    

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

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

  

  

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

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(2);

        //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
        canvas.drawRect(100,100,400,300,paint);

        //对画布进行平移操作
        canvas.translate(120,120);
        paint.setColor(Color.BLACK);

        //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
        // 所以这时距屏幕左上角的距离为(100+120,100+120)
        canvas.drawRect(100,100,400,300,paint);
        
        //再绘制一个蓝色的矩形 ,看看这个矩形是以平移前的画布左上角为原点还是以平移后的画布左上角为原点
        paint.setColor(Color.BLUE);
        canvas.drawRect(200,200,500,400,paint); 

 

 

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

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

  其实Canvas类还有 两个方法:

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

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

 举例:

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(2);

        //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
        canvas.drawRect(100,100,400,300,paint);
        canvas.save(); //保存当前画布状态

        //对画布进行平移操作
        canvas.translate(120,120);
        paint.setColor(Color.BLACK);

        //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
        // 所以这时距屏幕左上角的距离为(100+120,100+120)
        canvas.drawRect(100,100,400,300,paint);

        canvas.restore(); //恢复成栈顶保存的画布状态
        //再绘制一个蓝色的矩形 ,看看这个矩形是以平移前的画布左上角为原点还是以平移后的画布左上角为原点
        paint.setColor(Color.BLUE);
        canvas.drawRect(200,200,500,400,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(2);

        //先绘制一个 左上角坐标(100,100) 宽300 高200 的矩形
        canvas.drawRect(200,200,400,300,paint);

        //对画布进行旋转操作
        canvas.rotate(15);  // 控制旋转的角度,顺时针
        paint.setColor(Color.BLACK);

        //绘制一个宽300 高200 的矩形 ,因为画布向右平移了120px,向下平移了120px,
        // 所以这时距屏幕左上角的距离为(100+120,100+120)
        canvas.drawRect(200,200,400,300,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(2);

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

  

 

 

    

 

相关文章
|
定位技术 API
基于Leaflet.draw的自定义绘制实战
本文介绍了如何基于leaflet.draw进行自定义绘制,同时获取对象的bbox和geojson信息。
504 0
基于Leaflet.draw的自定义绘制实战
|
1月前
|
前端开发
自定义View绘制基础之Canvas
自定义View绘制基础之Canvas
39 0
|
6月前
|
存储 前端开发
canvas自定义绘制顺序解决遮挡问题
canvas自定义绘制顺序解决遮挡问题
76 0
|
8月前
|
前端开发 Android开发
Android 中使用Canvas绘制文字和矩形,将结果呈现在Bitmap上
Android 中使用Canvas绘制文字和矩形,将结果呈现在Bitmap上
141 0
|
C# 图形学
Winform控件优化之Paint事件实现圆角组件(提取绘制圆角的扩展方法)
Paint事件方法中实现圆角控件不要通过事件参数`e.ClipRectangle`获取控件区域范围,原因见最后介绍;注意设置控件背景透明(参见[Winform控件优化之背景透明那些事2...
638 0
Winform控件优化之Paint事件实现圆角组件(提取绘制圆角的扩展方法)
|
定位技术
Threejs使用Shapes实现不规则几何体,自定义绘图
Threejs使用Shapes实现不规则几何体,自定义绘图
771 0
Threejs使用Shapes实现不规则几何体,自定义绘图
|
Swift
SwiftUI极简教程32:使用Shape形状和Animation动画创建一个圆形进度条
SwiftUI极简教程32:使用Shape形状和Animation动画创建一个圆形进度条
627 0
SwiftUI极简教程32:使用Shape形状和Animation动画创建一个圆形进度条
|
前端开发 C#
WPF使用Canvas绘制可变矩形
原文:WPF使用Canvas绘制可变矩形 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WANGYAN9110/article/details/38130661 1、问题以及解决办法 最近因为项目需要,需要实现一个位置校对的功能,大致的需求如下:有一个图片,有一些位置信息,但是位置信息可能和实际有些偏差,需要做简单调整,后面会对这张图片进行切割等,做些处理。
1637 0
|
前端开发 Android开发
【Android 应用开发】Canvas 绘制文字 ( 文字尺寸测量 | 基线绘制 )
【Android 应用开发】Canvas 绘制文字 ( 文字尺寸测量 | 基线绘制 )
246 0
【Android 应用开发】Canvas 绘制文字 ( 文字尺寸测量 | 基线绘制 )
|
图形学
Unity 3D-Canvas画布的三种模式
Unity开发VR之Vuforia 本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) Chinar ...
1357 0