Flutter 的绘制主要涉及两个Widget: CustomPainter, CustomPaint

CustomPainter:提供画布的组件; 有几个主要的参数:

a. painter : 绘制的对象,是一个CustomPaint。它的绘制是在children之前。如果设置了children,该painter绘制的内容会被覆盖。 
b. foregroundPainter: 绘制的对象,是一个CustomPaint。它的绘制是在children之后。该painter绘制的内容会覆盖children 。 
c. size: 绘制区域的大小,如果有child就忽略此属性直接用child的size。
d. child :

CustomPaint:是一个抽象类,要实现绘制的逻辑必须继承该抽象类,并实现它的paint和shouldRepaint方法。

void paint(Canvas canvas, Size size);: 里边实现具体的绘制逻辑。

– canvas: 画布
– size: 画布的大小

bool shouldRepaint(covariant CustomPainter oldDelegate); : 控制是否重绘

绘制

Paint 画笔

介绍几个常用的参数: 
(1) color: 画笔的颜色
(2)strokeWidth: 线的宽度
(3)style: 填充模式,有两种: PaintingStyle.fill : 填充; PaintingStyle.stroke: 空心
(4)strokeCap:
(5)blendMode: 重叠部分的处理,一般在截取Image后合并Image用。
a. src: 只显示源图
b. dst: 只显示目标图
c. srcOver: 都显示,重叠部分是src覆盖在dst的上边;
d. dstOver: 都显示,重叠部分是dst覆盖在src的上边;
e. srcIn; // 只显示重叠部分的src图,透明部分也是不显示的。
f. dstIn; // 只显示重叠部分的dst图,透明部分也是不显示的。
… 还有好多不说了,用的时候自己看注释。

p = Paint()..color = Colors.orange // 画笔的颜色..strokeWidth = 2.0 // 线的宽度..style = PaintingStyle.stroke // fill: 填充, stroke: 空心..strokeCap = StrokeCap.butt // 转折处的处理..blendMode = BlendMode.dstIn; // 重叠处的处理模式,clear,src, dst, srcIn,dstIn等等。

绘制线段

// 第一个参数表示起点坐标
// 第二个参数表示终点坐标
// 第三个参数是画笔
canvas.drawLine(Offset(10, 10), Offset(100, 100), p);

绘制矩形

绘制矩形需要用到Rect, 而React的创建可以通过Offset和Size来完成,Offset 决定他左上角的坐标    Size 决定他的大小。Rect rect = offset & size;

// 矩形的长宽
Size size = Size(200, 300);
// 矩形左上角的坐标
Offset offset = Offset(200, 200);
// 合成Rect,为什么可以这样合成? 官方给的!看下边--->
Rect rect = offset & size;
canvas.drawRect(rect,Paint()..color = Colors.red..strokeWidth = 3.0);

/// A Rect can be created with one its constructors or from an [Offset] and a /// [Size] using the `&` operator: /// ///dart
/// Rect myRect = const Offset(1.0, 2.0) & const Size(3.0, 4.0);
/// ```

#### 绘制多边形
绘制多变形要用到Path的moveTo和lineTo放发,
void moveTo(double x, double y): 将画笔的起点移动到(x,y)坐标。
void lineTo(double x, double y): 从当前点绘制一条直线到(x,y)坐标。

canvas.drawPath(
    Path()
      …moveTo(30, 200)
      …lineTo(200, 200)
      …lineTo(100, 300)
      …lineTo(50, 330)
      …lineTo(30, 300)
      …close(),
    Paint()
      …color = Colors.lightBlue
      …strokeWidth = 1.0);

#### 绘制圆

// 第一个参数是原点坐标
// 第二个参数是半径
// 第三个参数是画笔
canvas.drawCircle(Offset(100, 100), 50, p);

#### 绘制阴影
```
// Path 的用法在上边绘制多变形的时候已经说过了 moveTo, lineTo .
canvas.drawShadow(Path()..moveTo(30.0, 30.0)..lineTo(320.0, 30.0)..lineTo(120.0, 160.0)..lineTo(30.0, 160.0)..close(),
// 阴影的颜色Colors.blue,
// 阴影扩散的范围3,false);

绘制文本

ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle(textAlign: TextAlign.left, // 对齐方式fontWeight: FontWeight.w600, // 粗体fontStyle: FontStyle.normal, // 正常 or 斜体fontSize: 18,
))..pushStyle(dartUi.TextStyle(color: Colors.black26))..addText('''// 测试文本的绘制// 绘制阴影canvas.drawShadow(Path()..moveTo(30.0, 30.0)..lineTo(320.0, 30.0)..lineTo(120.0, 160.0)..lineTo(30.0, 160.0)..close(),Colors.blue,3,false);''');
// 绘制的宽度
ParagraphConstraints pc =ParagraphConstraints(width: 350.0);
Paragraph paragraph = pb.build()..layout(pc);
canvas.drawParagraph(paragraph, Offset(30, 300));

绘制Image

绘制的代码如下,当然他有好几种绘制方式(drawImage, drawImageRect, drawImageNine)。代码看起来很简单,但是如果你直接这样写的话,是会报错的。折腾了我很久,最后找出的原因是 图片的加载是耗时的,不要放在这里边加载,放到外边加载完成后通过参数传进 CustomPainter 就不会报错了。 不信你直接在这里加载image然后在Future的then里去调用下面的代码,也是不行的!!!
一般用 canvas.drawImageRect 来绘制而不用canvas.drawImage。 canvas.drawImageRect可以指定宽高,可以截图。看一下源码你会发现drawImage 的内部也是调用drawImageRect 来实现的。
使用如下:

canvas.drawImage(image, dartUi.Offset(0, image.height.toDouble() + 30), Paint());
canvas.drawImageRect(image,// 本次要截取的区域--相对于原图(该坐标以原图的左上角为原点0,0, 截图一个宽高都为60的区域)Rect.fromLTWH(0, 0, 60, 60), // 要被截取的原图所在的区域Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()),Paint());

通过绘制实现图片的截图功能

// 裁剪画布,区域为(60, 60, 190, 90)
canvas.clipRect(Rect.fromLTWH(60, 60, 190, 90));

类似Android, 可以通过裁剪画布的功能做一些特殊的绘制。 一般裁剪之前会调用canvas.store ()来保存当前的画布,等到在裁剪过的画布上做完相关的操作之后可以通过 canvas.restore()来恢复之前的画布。 
canvas.store(): 保存当前的画布
canvas.restore ():恢复裁剪之前的画布(之前保存的) 
这俩要成对出现。 
可以跑的代码:

import 'package:flutter/material.dart';void main() =>runApp(StartPage());class StartPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: TestPage(),);}
}class TestPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("flutter 绘制demo"),),body: CustomPaint(foregroundPainter: PaintDemo(),),);}
}class PaintDemo extends CustomPainter {Paint _paint;PaintDemo() {_paint = Paint()..color = Colors.orange // 画笔的颜色..strokeWidth = 2.0 // 线的宽度..style = PaintingStyle.fill // fill: 填充, stroke: 空心;}@overridevoid paint(Canvas canvas, Size size) {canvas.drawLine(Offset(10, 10), Offset(60, 10), _paint);canvas.drawCircle(Offset(100, 100), 50, _paint);Size size = Size(200, 300);// 可以通过Offset和Size来创建一个Rect,Offset 决定他右上角的坐标    Size 决定他的大小Rect rect = Offset(200, 200) & size;canvas.drawRect(rect,Paint()..color = Colors.red..strokeWidth = 3.0);// 绘制阴影canvas.drawShadow(Path()..moveTo(30.0, 500.0)..lineTo(320.0, 500.0)..lineTo(120.0, 660.0)..lineTo(30.0, 660.0)..close(),Colors.blue,3,false);}@overridebool shouldRepaint(CustomPainter oldDelegate) {return true;}
}

到此, 关于Flutter的绘制就介绍的差不多了,欢迎指正。
关于图片的绘制,代码稍微多一些,没放上去,有需要留言。

Flutter 绘制Paint相关推荐

  1. Flutter绘制虚线的方法

    Flutter 自带的 Canvas 并没有 Android 中的 Canvas 那么强大,连虚线都不支持. 今天周日,下午抽时间写了两个 Canvas 扩展函数,实现了绘制虚线线段和虚线矩形. 效果 ...

  2. Flutter 画笔(Paint)、drawRect(绘制矩形)、PaintingStyle

    观察走在你前面的人,看看他为何领先,学习他的做法. drawRect(rect, paint) rect 矩形 paint 画笔 PaintingStyle.fill(用画笔填充绘制) Rect.fr ...

  3. Flutter 绘图 Paint strokeCap 延伸类型 strokeJoin 拐角类型 图文分析

    在 Flutter 绘图中,必然要使用一画笔,一般画笔的创建方法如下 //[定义画笔]Paint _paint = Paint()//画笔颜色..color = Colors.blue//画笔笔触类型 ...

  4. Flutter绘制指南06-颜色的基本操作

    本节目标 [1]. 认识Dart中的颜色表示方式 [2]. 了解颜色,[混合模式]的坐拥1 [3]. 了解如何读取图片中的像素颜色 一. 认识颜色 Color类在dart.ui包下,在Dart里面,颜 ...

  5. Flutter绘制指南09-动画曲线和方法

    本节目标 [1] 认识动画器[曲线速率]的作用 [2] 绘制出Flutter内置的所有曲线效果常量 [3] 了解动画器的常用方法 [4] 了解动画器的状态,以及状态变化监听 一.动画速率曲线 动画曲线 ...

  6. Flutter绘制指南10-手势在绘制中的使用

    本节目标 [1]. 了解手势在画布中的使用方式 [2]. 练习绘制,并根据手指滑动完成控制杆的绘制 [3]. 练习绘制,并根据手指滑动完成[刻度尺]的绘制 [4]. 了解如何限制绘制区域 一.控制柄组 ...

  7. flutter 绘制流水(水波上升)动态效果

    欢迎去浏览原文:http://tryenough.com/flutter-wave 效果 你可以先简单理解下贝塞尔曲线的原理: 推荐这个关于贝塞尔的教程:http://www.html-js.com/ ...

  8. Flutter绘制指南05-图形的路径添加

    本节目标 [1].了解如何通过移动路径形成形状:直线运动.圆弧运动.圆锥曲线运动.贝塞尔曲线运动 [2].了解路径的[绝对运动]和[相对运动] [3].了解已经在已有的路径中添加其他形状: 添加矩形, ...

  9. Flutter绘制布局工具

    给大家推荐一个在线绘制flutter布局的工具,对于一个flutter的菜鸟来说,这个工具入门还是很好的,Flutter Studio:FlutterStudio 附带两第一张是拖拽后的效果,第二张是 ...

最新文章

  1. AD学习笔记----PCB设计
  2. java对象的类型转换_Java对象的类型转换和属性复制
  3. boost::process::extend相关的测试程序
  4. 重构——30以类取代类型码(Replace Type Code with Class)
  5. 在ASP.NET页面中动态添加控件
  6. html之属性的定义
  7. centos更改MySQL数据库目录位置
  8. 【优化算法】可变步长LMS算法(VSS-LMS)【含Matlab源码 317期】
  9. java 数据库 程序_用java编写数据库程序的一般步骤
  10. Docker安装迅雷下载工具实现远程下载
  11. 远控免杀从入门到实践(2)工具总结篇
  12. SPX Instant Screen Capture 7.0 汉化已授权版
  13. sharedassets0_Unity3D研究院之mac上从.ipa中提取unity3D游戏资源(六十六)
  14. 回望2019,觅见2020
  15. 关于sematic segmentation的几篇论文(二)
  16. 低级程序员和高级程序员的区别
  17. 当我谈跑步时我谈些什么
  18. dos命令之 assoc 用法详解
  19. 高校教师开计算机培训中心,计算中心
  20. [专业课笔记] 单片机 第三章 指令系统

热门文章

  1. CRO 管理系统(附源码)
  2. manifestPlaceholders占位符失效
  3. Handsontable - getSourceData 和 getData 区别
  4. 太极计算机的销售模式,“人类周易太极八卦计算机”与“宇宙太极计算机”新模式...
  5. 南方人第一次到北方过冬是一种什么样的体验?
  6. P4799 [CEOI2015 Day2]世界冰球锦标赛
  7. 年终总结 | 盘点2020展望2021
  8. 修改JDK安装路径的作用
  9. maven-assembly-plugin maven自定义打包
  10. 免费23年的Java开始收费了,程序员怎么办?