抽象概念
想象你要画一幅画
画布(Canvas) = 一张白纸
画笔(Paint) = 颜料和画笔
画家(CustomPaint) = 你本人
简单比喻
Dart
CustomPaint(
painter:你的画笔工具 //画家使用技巧
size:画布大小 //纸张尺寸
)
核心三要素
Canvas + Paint + CustomPainter
一.简单案例入门
效果图

代码实例
Dart
import 'dart:async';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<StatefulWidget> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: CustomPaint(
size: Size(200, 200), //画布大小
painter: CirclePainter(),
),
)
);
}
}
class CirclePainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
//1.创建画笔
final paint = Paint()
..color = Colors.blue //颜色
..style = PaintingStyle.stroke //填充样式 ,fill就是填满,stroke是描边
..strokeWidth = 5; //边框宽度(如果使用描边)
//2.计算圆心位置(画布中心)
final center = Offset(size.width/2, size.height/2);
final radius = 50.0;
//3.绘制圆形
canvas.drawCircle(center, radius, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
二.绘制简单的图形集合
效果图

代码实例
Dart
body: CustomPaint(
size: Size(400, 400), //画布大小
painter: BasicShapesPainter(),
),
class BasicShapesPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
//画笔1:红色实心
final redPaint = Paint()
..color = Colors.red //颜色
..style = PaintingStyle.fill; //填充样式 ,fill就是填满,stroke是描边
//画笔2:蓝色描边
final bluePaint = Paint()
..color = Colors.blue
..style = PaintingStyle.stroke
..strokeWidth = 3;
//1.绘制矩形
canvas.drawRect(
Rect.fromLTRB(50, 50, 150, 150),//左上右下坐标,左和右是用x轴左边,上和下是用y轴坐标,屏幕左上角为圆点(0,0)
redPaint,
);
//2.绘制圆角矩形
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTRB(200, 50, 300, 150),
Radius.circular(20),
),
bluePaint
);
//3.绘制直线
canvas.drawLine(
Offset(50, 200),//起点
Offset(250, 200),//终点
bluePaint
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
Canvas坐标系
坐标系特点
Dart
原点 (0,0):在屏幕左上角
X 轴:向右为正方向
Y 轴:向下为正方向(这与数学坐标系不同!)
例子
Dart
Rect.fromLTRB(left, top, right, bottom)
表示
left: 矩形左边缘的 X 坐标 = 50
top: 矩形上边缘的 Y 坐标 = 50
right: 矩形右边缘的 X 坐标 = 150
bottom: 矩形下边缘的 Y 坐标 = 150
三.Paint的主要属性
Dart
Paint paint = Paint()
..color = Colors.blue // 颜色
..style = PaintingStyle.fill // 填充样式:fill填充 / stroke描边
..strokeWidth = 2.0 // 描边宽度
..strokeCap = StrokeCap.round // 线帽样式:round圆角 / butt直角 / square方头
..strokeJoin = StrokeJoin.round // 拐角样式:round圆角 / miter尖角 / bevel斜角
..blendMode = BlendMode.srcOver // 混合模式
..isAntiAlias = true // 抗锯齿
..filterQuality = FilterQuality.high // 过滤质量
..shader = gradient; // 渐变着色器
实现渐变案例
效果图

代码实例
Dart
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: CustomPaint(
size: Size(200, 200), //画布大小
painter: GradientPainter(),
),
);
}
}
class GradientPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
//创建线性渐变
final gradient = LinearGradient(
colors: [Colors.red,Colors.orange,Colors.yellow],
stops:[0.0,0.5,1.0]
);
final paint = Paint()
..shader = gradient.createShader(
Rect.fromLTWH(0, 0, size.width, size.height)
);
canvas.drawRect(
Rect.fromLTWH(0, 0, size.width, size.height),
paint
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
四.Path路径绘制
示例1:绘制简单形状
效果图

代码实例
Dart
class GradientPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeWidth = 4;
//创建路径
final path = Path();
//移动到起点(不划线)
path.moveTo(50, 50);
//画直线
path.lineTo(200, 50);
//画二次贝塞尔曲线
path.quadraticBezierTo(250, 100, 200, 150);
//画三次贝塞尔曲线
path.cubicTo(150, 200, 100, 100, 50, 150);
//闭合路径(连接到起点)
path.close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
示例2:绘制复杂形状
效果图

代码实例
Dart
class HeartShapePainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.purple
..style = PaintingStyle.fill;
//创建路径
final path = Path();
final centerX = size.width / 2;
final centerY = size.height / 2;
//移动到起点(不划线)
path.moveTo(centerX, centerY);
//绘制心形
path.cubicTo(
centerX + 50, centerY - 40,
centerX + 90, centerY - 20,
centerX, centerY + 60,
);
path.cubicTo(
centerX - 90, centerY - 20,
centerX - 50, centerY - 40,
centerX, centerY,
);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
示例3:绘制平行四边形
效果图

代码实例
Dart
class ShapePainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.green
..style = PaintingStyle.fill;
//创建路径
final path = Path();
//平行四边形倾斜角度
final skew = 30.0;
//4个顶点坐标
final p1 = Offset(skew, 0); // 左上
final p2 = Offset(size.width, 0); // 右上
final p3 = Offset(size.width - skew, size.height); // 右下
final p4 = Offset(0, size.height); // 左下
// 连接点形成平行四边形
path.moveTo(p1.dx, p1.dy);
path.lineTo(p2.dx, p2.dy);
path.lineTo(p3.dx, p3.dy);
path.lineTo(p4.dx, p4.dy);
path.close(); // 闭合路径
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}