【Flutter 专题】36 自定义 View 之 Canvas (三)

和尚继续学习 Canvas 的相关方法:

drawVertices 绘制顶点

和尚上次没有整理 drawVertices 的绘制方法,这次补上;Vertice 即顶点,通过绘制多个顶点,在进行连线,多用于 3D 模型中;

drawVertices 包括三个参数,第一个是顶点属性,根据不同属性线的连接方式也不同;第二个是混合模式,即线的颜色与背景色混合效果;第三个是画笔,和尚测试调整 Paint 线的粗细无法调整整体连线的粗细;

和尚借用 A B C D E F G H I 顶点来简单介绍:

  1. VertexMode.triangles:每三个分割顶点相连,即 [A B C] [D E F] [G H I] 共 3 组;
  2. VertexMode.triangleStrip:每相邻的三个顶点相连,即 [A B C] [B C D] [C D E] [D E F] [E F G] [F G H] [G H I] 共 7 组;
  3. VertexMode.triangleFan:每相邻的两个顶点与首点相连,即 [A B C] [A C D] [A D E] [A E F] [A F G] [A G H] [A H I] 共 7 组;
canvas.drawVertices(
    Vertices(VertexMode.triangles, [
      Offset(30, 30), Offset(30, 60),Offset(60, 60),
      Offset(90, 60), Offset(120, 60), Offset(120, 30),
      Offset(60, 90), Offset(60, 120), Offset(90, 120),
    ]),
    BlendMode.colorBurn, Paint()..color = Colors.red);

canvas.drawVertices(
    Vertices(VertexMode.triangleStrip, [
      Offset(210, 30), Offset(210, 60), Offset(240, 60),
      Offset(270, 60), Offset(300, 60), Offset(300, 30),
      Offset(240, 90), Offset(240, 120), Offset(270, 120),
    ]),
    BlendMode.colorBurn, Paint()..color = Colors.green);

canvas.drawVertices(
    Vertices(VertexMode.triangleFan, [
      Offset(120, 150), Offset(120, 180), Offset(150, 180),
      Offset(180, 180), Offset(210, 180), Offset(210, 150),
      Offset(150, 210), Offset(150, 240), Offset(180, 240),
    ]),
    BlendMode.colorBurn, Paint()..color = Colors.blue);

画布操作

和尚接下来介绍一下画布的基本操作,与 Android 很相似;

scale 缩放

scale 即缩放效果,缩放的是画布大小,可以设置缩放倍数,且缩放倍数会叠加;

canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
// 缩放
canvas.scale(2);

canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
// 缩放
canvas.scale(0.25);

canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
translate 平移

translate 即平移,平移的也是画布,并非画布中子元素,两个参数分别为水平方向和竖直方向距离;

canvas.drawLine(
    Offset(0, 0), Offset(60, 60),
    Paint()..color = Colors.red..strokeWidth = 2);
canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
// 平移
canvas.translate(30, 90);

canvas.drawLine(
    Offset(0, 0), Offset(0, Screen.height),
    Paint()..color = Colors.blueGrey..strokeWidth = 2);
canvas.drawLine(
    Offset(0, 0), Offset(Screen.width, 0),
    Paint()..color = Colors.blueGrey..strokeWidth = 2);
canvas.drawLine(
    Offset(0, 0), Offset(60, 60),
    Paint()..color = Colors.red..strokeWidth = 2);
canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0.style = PaintingStyle.stroke);
rotate 旋转

rotate 即旋转,原点为屏幕左上角,和尚为了效果先将画布平移一部分到屏幕中间在进行旋转测试,注意参数并非角度而是对应的 PI 值;

canvas.drawLine(
    Offset(0, 0), Offset(60, 60),
    Paint()..color = Colors.red..strokeWidth = 2);
canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
// 以当前原点旋转 90 度
canvas.rotate(degToRad(90));

canvas.drawLine(
    Offset(0, 0), Offset(60, 60),
    Paint()..color = Colors.green..strokeWidth = 2);
canvas.drawRect(
    Rect.fromLTWH(60, 60, 90, 50),
    Paint()..color = Colors.green
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
skew 斜切

skew 即斜切,两个参数为水平方向和竖直方向切度值,值为三角函数中的 tan 值,即 45 度时 tan 值为 1

canvas.drawRect(
    Rect.fromLTWH(60, 0, 90, 50),
    Paint()..color = Colors.red
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
// 水平方向斜近 30 度,竖直方向不变
canvas.skew(0.6, 0);

canvas.drawRect(
    Rect.fromLTWH(60, 0, 90, 50),
    Paint()..color = Colors.green
      ..strokeWidth = 2.0..style = PaintingStyle.stroke);
save/restore 保存/恢复

save/savelayer 即保存当前画布,restore 即恢复当前画布,也可以理解为清空重新绘制;save/restore 可以多次,以栈的方式存储,可以通过进栈/出栈到当具体某一层;但是和尚测试时发现与 save/restore 需要成对出现,否则回报不匹配异常;

canvas.clipRect(Rect.fromLTWH(40, 40, Screen.width - 80, Screen.width - 80));
canvas.drawColor(Colors.green, BlendMode.srcIn);
// 保存画布1
canvas.save();

canvas.clipRect(
    Rect.fromLTWH(60, 60, Screen.width - 120, Screen.width - 120));
canvas.drawColor(Colors.grey, BlendMode.srcIn);
// 保存画布2
canvas.save();
canvas.clipRect(
    Rect.fromLTWH(80, 80, Screen.width - 160, Screen.width - 160));
canvas.drawColor(Colors.orange, BlendMode.srcIn);
//  canvas.save();
// 恢复画布1
canvas.restore();
// 恢复画布2
canvas.restore();
//  canvas.restore();
canvas.drawColor(Colors.blue, BlendMode.srcIn);

Canvas 非常强大,还有很多研究不透彻的地方,和尚仍在不断学习,有错误的地方烦请多多指点

本文分享自微信公众号 - 阿策小和尚(gh_8297e718c166)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏front-end technology

canvas的api的学习(一)

Canvas是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作

12150
来自专栏GA小站

用户的唯一性识别

不同的设备终端数识别的人方式不同,基本原则都是通过尽量通过各种唯一的ID去作为人的唯一标识,具体如下表:

55830
来自专栏front-end technology

canvas的api总结

Canvas是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作

8510
来自专栏grain先森

微信小程序之圆形进度条

(1)使用2个canvas 一个是背景圆环,一个是彩色圆环。 (2)使用setInterval 让彩色圆环逐步绘制。

11620
来自专栏芋道源码1024

8 款好用超赞的 Google Chrome 插件,一直用,一直爽

Github一个不好的地方就是代码是不能相互跳转的,所以阅读起来很累,如果我要引入一个库,那么就必须clone下来然后通过idea打开才行。这样的流程对于库的前...

25720
来自专栏call_me_R

前端谈谈实现五子棋

秉承着会就分享,不会就折腾的技术宗旨。自己利用周末的时间将休闲小游戏-五子棋重新梳理了一下,整理成一个小的教程,分享出来给大家指点指点。

10620
来自专栏无人打理的花园

[pixlate] 用 canvas 转像素画

几周前看到这个像素猫的效果,这个版本的实现原理是 box-shadow,我想到用 grid 也可以实现一遍。接着发散到了“如何将任意图片像素化”上。

14920
来自专栏终身开发者

Android实现长图截取、拼接和添加水印

本文的讨论是基于手机在没有root情形。 早期版本的Android是没有提供截屏功能的,到4.0时代后才自带了音量Down+电源键截屏的功能。在开发过程中还可以...

21610
来自专栏front-end technology

canvas的api的学习(一)

Canvas是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作

9420
来自专栏Vue源码 & 前端进阶体系

【怕啥弄啥系列】Canvas - 基础图形绘制

HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.

11630

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励