Flutter中CustomPaint绘制图形的不详细食用手册

本文章已废弃,详细请查看以下文章代替:
Flutter学习:认识CustomPaint组件和Paint对象
Flutter学习:使用CustomPaint绘制路径
Flutter学习:使用CustomPaint绘制图形
Flutter学习:使用CustomPaint绘制文字
Flutter学习:使用CustomPaint绘制图片

CustomPaint

CustomPaint是flutter的一个组件,所以我们可以像其他组件一样使用:

CustomPaint({ 
  Key? key, 
  CustomPainter? painter,  // 在子元素之前绘制
  CustomPainter? foregroundPainter,  // 在子元素之后绘制
  Size size = Size.zero,  // 约定的布局大小,默认为子元素的大小
  bool isComplex = false,  // 绘制复杂的图形时应为 true
  bool willChange = false,  // 在下一帧时是否会发生改变
  Widget? child,  // 子元素
})

CustomPaint中最重要的就是painter属性,通过继承CustomPainter类,可以绘制任何自定义的图形。

在继承CustomPainter后有两个必须重写的方法,在paint方法中进行绘制操作,shouldRepaint方法用来描述绘制的更新频率,一般来说只有在当前改变了绘制的图形时才返回true

class MyCustomPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => this != oldDelegate;
}

前提代码:

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomPaint(
        painter: MyCustomPainter(),
        size: Size.infinite,
      ),
    );
  }
}

Paint

Paint相当于一支画笔,可以自定义画笔的颜色、粗细等。首先用Paint类实例化一个对象

Paint paint = Paint();

Paint类和绘制内容相关的属性一共有14个

style

stylePaintStyle?,是否绘制内部形状,形状的边缘,或两者都绘制

// 填充(默认)
paint.style = PaintingStyle.fill; 
// 描边
paint.style = PaintingStyle.stroke;

image

Color

colorColor?,描边或填充形状时使用的颜色。

// 默认为不透明黑色Colors.black
paint.color = Colors.red;

image

colorFilter

colorFilter ColorFilter?,绘制形状或合成图层时应用的颜色过滤器,绘制形状时, colorFilter会覆盖colorshader

// 构造一个将 sRGB 伽马曲线应用于 RGB 通道的滤色器
paint.colorFilter = const ColorFilter.linearToSrgbGamma();
// 创建一个颜色过滤器,将 sRGB 伽马曲线的倒数应用于 RGB 通道
paint.colorFilter = const ColorFilter.srgbToLinearGamma();
// 构造一个通过 5x5 矩阵转换颜色的滤色器,其中第五行隐式添加到标识配置中。
// 每个像素的颜色值,表示为<code>R, G, B, A</code> ,乘以矩阵以创建新颜色:
// | R' |   | a00 a01 a02 a03 a04 |   | R |
// | G' |   | a10 a11 a22 a33 a44 |   | G |
// | B' | = | a20 a21 a22 a33 a44 | * | B |
// | A' |   | a30 a31 a22 a33 a44 |   | A |
// | 1  |   |  0   0   0   0   1  |   | 1 |
// 矩阵按行优先顺序排列,转换列在未归一化的 0...255 空间中指定。
paint.colorFilter = const ColorFilter.matrix([
      1, 0, 0, 0, 0,
      0, 1, 0, 0, 0,
      0, 0, 1, 0, 0,
      0, 0, 0, 1, 0,
]);
// 创建一个颜色过滤器,应用作为第二个参数给出的混合模式
// 源颜色是作为第一个参数给出的颜色,目标颜色是来自正在合成的图层的颜色
paint.colorFilter = const ColorFilter.mode(Colors.blue, BlendMode.colorBurn);

image

invertColors

invertColorsbool?, 绘制时图像的颜色是否反转。 反转图像的颜色会应用一个新的滤色器,该滤色器将与任何用户提供的滤色器组成。

paint.invertColors = true;

image

isAntiAlias

isAntiAliasbool?,是否对画布上绘制的线条和图像应用抗锯齿,使用了抗锯齿边缘更平滑。

// 默认值为true
paint.isAntiAlias = true;

image

strokeCap

strokeCapStrokeCap?,当style设置为PaintingStyle.stroke时放置在画线末端的饰面

// 以平坦边缘开始和结束轮廓,没有延伸
paint.strokeCap = StrokeCap.butt;
// 以半圆形延伸开始和结束轮廓
paint.strokeCap = StrokeCap.round;
// 以半方形扩展开始和结束轮廓。这类似于将每个轮廓扩展一半笔画宽度(由Paint.strokeWidth绘制)
paint.strokeCap = StrokeCap.square;

image

strokeJoin

strokeJoinStrokeJoin?,放置在段之间的连接处的那种饰面,只适用于绘制路径(即PaintingStyle.stroke)。

// 线段之间的连接将线段对接端的角连接起来,以提供斜切外观
paint.strokeJoin = StrokeJoin.bevel;
// 线段之间的连接形成尖角
paint.strokeJoin = StrokeJoin.miter;
// 线段之间的连接是半圆形的
paint.strokeJoin = StrokeJoin.round;

image

strokeMiterLimit

strokeMiterLimitdouble?,当连接设置为StrokeJoin.miterstyle设置为PaintingStyle.stroke时,在线段上绘制斜接的限制。如果超出此限制,则会改为绘制StrokeJoin.bevel连接。

关于strokeMiterLimit是什么可以查看以下文章:

// 默认为4.0
paint.strokeWidth = 20;

image

strokeWidth

strokeWidthdouble?,当style设置为PaintingStyle.stroke时绘制边缘的宽度。

// 默认值为0.0
paint.strokeWidth = 20;

image

shader

shaderShader?,用来描边或填充形状时使用的着色器。当它为空时,将使用color。

shader属性传递的值为 Gradient 或 ImageShader对象。

关于shader的使用方法可以查看以下文章:

blendMode

blendModeBlendMode?,在画布上绘画时使用的算法。在画布上绘制形状或图像时,可以使用不同的算法来混合像素。

关于BlendMode的相关资料可以查看以下文章:

filterQuality TODO

filterQualityFilterQuality?

用于对图像进行采样的ImageFilterShader对象中的图像采样以及用于渲染图像的Canvas操作的质量级别。
当按比例放大时,质量通常是最低的, lowmedium的质量none ,而对于非常大的比例因子(超过 10 倍),质量最高的是high
缩小时, medium提供最佳质量,尤其是在将图像缩小到小于其大小的一半或在此类缩小之间为比例因子设置动画时。否则, lowhigh在 50% 和 100% 之间的减少提供类似的效果,但图像可能会丢失细节并具有低于 50% 的丢失。
为了在放大和缩小图像或比例未知时获得高质量, medium通常是一个很好的平衡选择。

paint.filterQuality = FilterQuality.none;
paint.filterQuality = FilterQuality.low;
paint.filterQuality = FilterQuality.medium;
paint.filterQuality = FilterQuality.high;

imageFilter TODO

paint.imageFilter

maskFilter TODO

paint.maskFilter = MaskFilter.blur(_style, _sigma);

Canvas

canvas绘制的所有内容都是以屏幕左上角为原点,右边和下边为正方向延伸的直角坐标系。

image

drawCircle 绘制圆形

drawCircle需要传递3个参数:

  • Offset c 圆心的位置坐标
  • double radius 圆的半径
  • Paint paint 绘画对象
// 以左上角为圆心绘制
canvas.drawCircle(const Offset(0, 0), 100, paint);
// 以中心点为圆心绘制
canvas.drawCircle(size.center(Offset.zero), 100, paint);
// 以右下角为圆心绘制
canvas.drawCircle(Offset(size.width, size.height), 100, paint);![CustomPaint_drawCircle]

image

drawRect 绘制矩形

drawCircle需要传递2个参数:

  • Rect rect Rect对象
  • Paint paint 绘制对象

创建Rect对象的方法有7种:

Rect.zero

绘制一个左、上、右和下边缘都为零的矩形

Rect rect = Rect.zero;
canvas.drawRect(rect, paint);

Rect.largest

绘制一个覆盖整个坐标空间的矩形

Rect rect = Rect.largest;
canvas.drawRect(rect, paint);

image

Rect.fromCenter

确定一个矩形的中心点坐标来绘制。

Rect.fromCenter({ required Offset center, required double width, required double height})需要传递3个参数:

  • center用来设置矩形的中心点坐标
  • width用来设置矩形的宽
  • height用来确定矩形的高
Offset center = size.center(Offset.zero);
Rect rect = Rect.fromCenter(center: center, width: 250, height: 250);
canvas.drawRect(rect, paint);

image

Rect.fromLTRB

从左、上、右和下边缘构造一个矩形

Rect.fromLTRB( double left, double top, double right, double bottom)需要传递4个参数:

  • left代表左上角顶点的x坐标
  • top代表左上角顶点的y坐标
  • right代表右下角顶点的x坐标
  • bottom代表右下角顶点的y坐标
Rect rect = const Rect.fromLTRB(50, 300, 350, 500);
canvas.drawRect(rect, paint);

image

Rect.fromCircle

构造一个以给定圆为边界的矩形

Rect.fromCircle({required Offset center, required double radius})需要传递2个对象:

  • center用来设置圆的圆心左标
  • radius用来设置圆的半径
Offset center = size.center(Offset.zero);
Rect rect = Rect.fromCircle(center: center, radius: size.width / 3);
canvas.drawRect(rect, paint);

image

Rect.fromLTWH

通过左上角点的坐标和宽度、高度来构造一个矩形

Rect.fromLTWH( double left, double top, double width, double height)需要传递4个参数:

  • left用来设置左上角的x坐标
  • top用来设置左上角的y坐标
  • width用来设置矩形的宽
  • height用来设置矩形的高
Rect rect = const Rect.fromLTWH(50, 220, 300, 300);
canvas.drawRect(rect, paint);

image

Rect.fromPoints

通过两个坐标点来绘制矩形。

Rect.fromPoints(Offset a, Offset b)需要传递两个Offset对象:

  • a代表左上角点的坐标
  • b代表右下角的点的坐标
Rect rect = Rect.fromPoints(const Offset(60, 200), const Offset(320, 500));
canvas.drawRect(rect, paint);

image

drawRRect 绘制圆角矩形

RRect.zero

绘制一个左、上、右和下边缘都为零的圆角矩形,和Rect.zero效果一样

RRect rrect = RRect.zero;

RRect.fromRectAndRadius

通过绘制一个矩形再设置圆角半径来绘制圆角矩形

RRect RRect.fromRectAndRadius(Rect rect, Radius radius)需要传递2个参数:

  • rect是一个矩形对象
  • radius为矩形设置圆角
Rect rect = Rect.fromPoints(const Offset(50, 200), const Offset(320, 600));
RRect rrect = RRect.fromRectAndRadius(rect, const Radius.circular(40.0));
canvas.drawRRect(rrect, paint);

image

RRect.fromLTRBR

RRect.fromLTRBR(double left, double top, double right, double bottom, Radius radius)需要传递5个参数,前4个参数和Rect.fromLTRB一样:

  • left代表左上角顶点的x坐标
  • top代表左上角顶点的y坐标
  • right代表右下角顶点的x坐标
  • bottom代表右下角顶点的y坐标
  • radius用来设置矩形的圆角半径
RRect rrect = RRect.fromLTRBR(80, 120, 320, 420, const Radius.circular(48));
canvas.drawRRect(rrect, paint);

image

RRect.fromLTRBXY

RRect.fromLTRBXY( double left, double top, double right, double bottom, double radiusX, double radiusY)需要传递6个参数,前4个参数和Rect.fromLTRB一样:

  • left代表左上角顶点的x坐标
  • top代表左上角顶点的y坐标
  • right代表右下角顶点的x坐标
  • bottom代表右下角顶点的y坐标
  • radiusX用来设置x方向的半径长度
  • radiusY用来设置y方向的半径长度
RRect rrect = const RRect.fromLTRBXY(50, 150, 320, 530, 90, 60);
canvas.drawRRect(rrect, paint);

image

RRect.fromLTRBAndCorners

从其左、上、右和下边缘以及 topLeft、topRight、bottomRight 和 bottomLeft 半径构造一个圆角矩形

RRect.fromLTRBAndCorners(
  double left, double top, double right, double bottom, {
    Radius topLeft = Radius.zero,
    Radius topRight = Radius.zero, 
    Radius bottomRight = Radius.zero,
    Radius bottomLeft = Radius.zero
})

可以传递8个参数,其中4个为必选的参数:

  • left代表左上角顶点的x坐标
  • top代表左上角顶点的y坐标
  • right代表右下角顶点的x坐标
  • bottom代表右下角顶点的y坐标
  • topLeft用来设置左上角的圆角半径
  • topRight用来设置右上角的圆角半径
  • bottomRight用来设置右下角角的圆角半径
  • bottomLeft用来设置左下角的圆角半径
RRect rrect = RRect.fromLTRBAndCorners(50, 120, 320, 420,
  topLeft: const Radius.circular(20),
  topRight: const Radius.circular(40),
  bottomLeft: const Radius.circular(60),
  bottomRight: const Radius.circular(80));
canvas.drawRRect(rrect, paint);

image

RRect.fromRectXY

根据方法名可以看出,需要依据一个矩形来绘制

RRect.fromRectXY( Rect rect, double radiusX, double radiusY)需要传递3个参数:

  • rect用来绘制一个矩形

  • radiusX用来设置x方向的半径长度

  • radiusY用来设置y方向的半径长度

Rect rect = Rect.fromPoints(const Offset(50, 180), const Offset(300, 420));
RRect rrect = RRect.fromRectXY(rect, 60.0, 100.0);
canvas.drawRRect(rrect, paint);

image

RRect.fromRectAndCorners

RRect.fromRectAndCorners( Rect rect,{ Radius topLeft = Radius.zero, Radius topRight = Radius.zero, Radius bottomRight = Radius.zero, Radius bottomLeft = Radius.zero})可以传递5个参数,1个必要的,4个可选的:

  • rect用来绘制一个矩形
  • bottom代表右下角顶点的y坐标
  • topLeft用来设置左上角的圆角半径
  • topRight用来设置右上角的圆角半径
  • bottomRight用来设置右下角角的圆角半径
  • bottomLeft用来设置左下角的圆角半径
Rect rect = Rect.fromPoints(const Offset(40, 125), const Offset(330, 520));
RRect rrect = RRect.fromRectAndCorners(rect,
  topLeft: const Radius.circular(60),
  topRight: const Radius.circular(40),
  bottomLeft: const Radius.circular(80),
  bottomRight: const Radius.circular(20));
canvas.drawRRect(rrect, paint);

image

drawArc 绘制圆弧

drawArc绘制一个以矩形为参照物的圆弧,需要传递5个属性:

  • Rect rect 矩形的位置和大小
  • double startAngle 圆弧开始的角度
  • double sweepAngle 圆弧开始到结束的角度大小
  • bool useCenter 是否向中心闭合
  • Paint paint 绘画对象
Rect rect = Rect.fromCenter(center: size.center(Offset.zero), width: 200, height: 200);
// 闭合
canvas.drawArc(rect, 0, 3.14, true, paint);
// 不闭合
canvas.drawArc(rect, 0, 3.14, false, paint);

image

drawColor 绘制颜色

drawColor绘制的颜色会沾满子整个屏幕。需要传递2个参数:

  • Color color 要绘制的颜色
  • BlendMode blendMode 颜色的混合模式
canvas.drawColor(Colors.blue, BlendMode.darken);

drawShadow

绘制阴影

drawShadow(Path path, Color color, double elevation, bool transparentOccluder)需要传递4个参数:

  • path是需要绘制阴影的路径
  • color是阴影的颜色
  • elevation是阴影的高度
  • transparentOccluder表示如果遮挡对象是透明的,应该为true,否则为false
Path path = Path();
path.moveTo(80, 200);
path.lineTo(320, 400);
path.lineTo(200, 340);
path.lineTo(100, 460);
path.close();
canvas.drawShadow(path, Colors.black, 8.0, false);
canvas.drawPath(path, paint);

image

drawVertices TODO

drawDRRect 绘制嵌套圆角矩形

drawDRRect绘制嵌套的两个矩形,outer圆角矩形的宽高必须大于等于inner圆角矩形的宽高。需要传递3个参数:

  • RRect outer 绘制外围圆角矩形
  • RRect inner 绘制内部圆角矩形
  • Paint paint 绘画对象
// 外围圆角矩形
Rect rectOuter = Rect.fromCenter(center: size.center(Offset.zero), width: 300, height: 300);
RRect outer = RRect.fromRectAndRadius(rectOuter, const Radius.circular(80));
// 内部圆角矩形
Rect rectInner = Rect.fromCenter(center: size.center(Offset.zero), width: 200, height: 100);
RRect inner = RRect.fromRectAndRadius(rectInner, const Radius.circular(60));
canvas.drawDRRect(outer, inner, paint);

image

drawLine 绘制线段

drawLine需要传递3个参数:

  • Offset p1 第一个点的位置
  • Offset p2 第二个点的位置
  • Paint paint 绘制对象
Offset p1 = const Offset(200, 50);
Offset p2 = const Offset(600, 200);
canvas.drawLine(p1, p2, paint);

image

drawOval 绘制椭圆

drawOval绘制一个轴对齐的椭圆。需要传递2个参数:

  • Rect rect 获取椭圆的原点和宽高
  • Paint paint 绘制对象
// 宽高不相等为椭圆
Rect rect = Rect.fromCenter(center: size.center(Offset.zero), width: 300, height: 200);
canvas.drawOval(rect, paint);
// 宽高相等为正圆
Rect rect = Rect.fromCenter(center: size.center(Offset.zero), width: 300, height: 300);
canvas.drawOval(rect, paint);

image

drawPaint 绘制点

drawPaint根据给定的PointMode绘制一系列点。需要传递3个参数:

  • PointMode pointMode 点的绘制模式
  • List points 点的坐标
  • Paint paint 绘制对象
List<Offset> points = const [
  Offset(100, 100), Offset(200, 200),
  Offset(100, 300), Offset(300, 400),
  Offset(200, 500), Offset(300, 400),
];
// 绘制多条线段,两个点一组
canvas.drawPoints(PointMode.lines, points, paint);
// 绘制点,由strokeCap控制点的样式
canvas.drawPoints(PointMode.points, points, paint);
// 将每一个点连接起来
canvas.drawPoints(PointMode.polygon, points, paint);

image

drawRawPoints TODO

drawPath 绘制路径

drawPath需要传递2个参数:

  • Path path 路径对象
  • Paint paint 绘制对象
Path path = Path()..moveTo(100, 100);
path.lineTo(250, 250);
path.lineTo(350, 180);
path.lineTo(200, 500);
// 控制路径是否闭合,可不写
path.close();
canvas.drawPath(path, paint);

image

path.moveTo和path.lineTo

path.moveTopath.lineTo一样,都需要传递2个参数:

  • double x用来设置点的横坐标(x轴)
  • double y用来设置点的纵坐标(y轴)
path.moveTo(80, 200);
path.lineTo(320, 400);
canvas.drawPath(path, paint);

其中p0path.moveTo设置的坐标,p1path.lineTo设置的坐标

image

path.relativeMoveTo和path.relativeLineTo

path.relativeMoveTopath.relativeLineTofiType的使用方法和path.moveTopath.lineTo一样,只是起始点不再是左上角,而是前一个点的坐标

关于fillType的资料可以查看以下文章:

fillType有两个枚举值:

Path path = Path()..moveTo(size.width / 2, 200);
path.lineTo(size.width / 4, 500);
path.lineTo(size.width / 7 * 6, 320);
path.lineTo(size.width / 7, 320);
path.lineTo(size.width / 4 * 3, 500);
path.close();
// 默认值
path.fillType = PathFillType.nonZero;
path.fillType = PathFillType.evenOdd;
canvas.drawPath(path, paint);

image

path.addArc

通过路径绘制圆弧

addArc(Rect oval, double startAngle, double sweepAngle)需要传递3个参数:

  • oval绘制一个矩形
  • startAngle圆弧开始处
  • sweepAngle圆弧开始到结束的角度大小
// 只有path.addArc方法,path.moveTo方法将会无效
Path path = Path();
// path.moveTo(size.width / 2, 200); 无效
Rect oval = Rect.fromPoints(const Offset(80, 80), const Offset(300, 180));
path.addArc(oval, 0, 4);
canvas.drawPath(path, paint);
// 有path.moveTo、path.lineTo、path.addArc这3个方法
// path.lineTo在谁的后面就跟谁连接,默认path.moveTo为(0,0)
Path path = Path();
path.moveTo(size.width / 2, 200);
Rect oval = Rect.fromPoints(const Offset(80, 80), const Offset(300, 180));
path.addArc(oval, 0, 4);
path.lineTo(250, 400);
canvas.drawPath(path, paint);

path.addOval、path.addRect、path.addRRect用法和path.addArc一样

path.addPath TODO

该方法将复制一遍已绘制的路径,并进行偏移

addPath(Path path, Offset offset, {Float64List? matrix4})可以传递3个参数,2个必要的,一个可选的:

  • path已绘制的路径对象
  • offsetpath对象进行的偏移量
  • matrix4
Path path = Path();
// path.addArc、path.moveTo、path.lineTO这3个方法位置不同绘制的效果不同
// path.moveTo → path.addArc → path.lineTO时path.moveTo将会无效
// path.addArc → path.moveTo → path.lineTO时path.moveTo将会无效
Rect oval = Rect.fromPoints(const Offset(80, 80), const Offset(300, 180));
path.addArc(oval, 0, 4);
path.lineTo(250, 400);
path.lineTo(320, 310);
// 路径是否闭合,
path.close();
canvas.drawPath(path, paint);

path.addPolygon

添加一条新路径

addPolygon(List points, bool close)需要传递2个参数:

  • points一系列点的坐标
  • close是否首位相连
path.moveTo(size.width / 2, 200);
path.lineTo(200, 380);
path.lineTo(80, 460);
List<Offset> points = const [
  Offset(100, 40),
  Offset(350, 240),
  Offset(200, 500),
];
path.addPolygon(points, true);
canvas.drawPath(path, paint);

image

path.arcTo

绘制圆弧路径

arcTo( Rect rect, double startAngle, double sweepAngle, bool forceMoveTo, )需要传递4个参数:

  • rect绘制一个矩形用来确定圆弧的位置
  • startAngle圆弧开始的角度
  • sweepAngle圆弧开始到结束的角度大小
  • forceMoveTo圆弧路径为新路径还是与原路径相连
path.moveTo(size.width / 2, 200);
path.lineTo(80, 460);
Rect rect = Rect.fromPoints(const Offset(80, 340), const Offset(280, 420));
// forceMoveTo为true
path.arcTo(rect, 0, 5, true);
// forceMoveTo为false
path.arcTo(rect, 0, 5, false);
canvas.drawPath(path, paint);

image

path.arcToPoint

绘制一个两点之间线段距离的直径圆弧

arcToPoint(Offset arcEnd, {Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true})可以传递5个参数,1个必要的,4个可选的:

  • arcEnd确定圆弧的结束点坐标
  • radius为0时将绘制一条直线
  • rotation感觉没啥用
  • largeArc是否是大圆弧
  • clockwise决定圆弧的绘制是从左边还是右边
path.moveTo(100, 200);
// p0
path.arcToPoint(
  const Offset(320, 500),
  radius: const Radius.circular(.5),
  rotation: 2,
  argeArc: true,
  clockwise: false,
);
// p1
path.arcToPoint(
  onst Offset(160, 250),
  adius: const Radius.circular(1),
  otation: 0,
  argeArc: true,
  lockwise: false,
);
// p2
path.arcToPoint(
  const Offset(240, 375),
  radius: const Radius.circular(0),
  rotation: 5,
  largeArc: false,
  clockwise: true,
);
canvas.drawPath(path, paint);

image

path.relativeArcToPoint

效果和path.arcToPoint一样,只是起始点为前一个点

path.conicTo

绘制圆锥路径

conicTo(double x1, double y1, double x2, double y2, double w)需要传递5个参数:

  • x1是第一个点x轴的坐标
  • y1是第一个点y轴的坐标
  • x2是第二个点x轴的坐标
  • y2是第二个点y轴的坐标
  • w是权重值。如果权重大于1,则曲线为双曲线;如果权重等于 1,则为抛物线;如果小于 1,则为椭圆
path.moveTo(size.width / 2, 200);
// 权重=0
path.conicTo(80, 280, 300, 380, 0);
// 权重=1
path.conicTo(80, 280, 300, 380, 1);
// 权重=2
path.conicTo(80, 280, 300, 380, 2);
canvas.drawPath(path, paint);

image

path.relativeConicTo

效果和path.conicTo一样,只是起始点为前一个点

path.quadraticBezierTo

使用控制点 (x1,y1) 添加一个从当前点弯曲到给定点 (x2,y2) 的二次贝塞尔曲线段

quadraticBezierTo( double x1, double y1, double x2, double y2)需要传递4个参数:

  • x1是第一个点x轴的坐标
  • y1是第一个点y轴的坐标
  • x2是第二个点x轴的坐标
  • y2是第二个点y轴的坐标
path.moveTo(20, 200);
path.quadraticBezierTo(200, 80, size.width - 20, size.width);
canvas.drawPath(path, paint);

其中p0代表起始点位置(path.moveTo(20, 200)),p1的坐标是(x1, y1)p2的坐标是(x2, y2)

image

path.relativeQuadraticBezierTo

效果和path.quadraticBezierTo一样,只是起始点为前一个点

path.cubicTo

使用控制点 (x1,y1) 和 (x2,y2) 添加从当前点弯曲到给定点 (x3,y3) 的三次贝塞尔曲线段

cubicTo( double x1, double y1, double x2, double y2, double x3, double y3)需要传递6个参数:

  • x1是第一个点x轴的坐标
  • y1是第一个点y轴的坐标
  • x2是第二个点x轴的坐标
  • y2是第二个点y轴的坐标
  • x3是第三个点x轴的坐标
  • y3是第三个点y轴的坐标
path.moveTo(100, 200);
path.cubicTo(120, 120, 240, 360, 310, 360);
canvas.drawPath(path, paint);

其中p1代表p0点控制线的右边坐标,p2代表p3点控制线的左边坐标

image

path.relativeCubicTo

效果和path.cubicTo一样,只是起始点为前一个点

path.extendWithPath TODO

path.getBounds

获取路径的边界矩形

path.moveTo(50, 200);
path.lineTo(300, 280);
// path.getBounds()的结果为Rect.fromLTRB(50.0, 200.0, 300.0, 280.0)
print(path.getBounds());
canvas.drawPath(path, paint);

image

path.reset

清除所有子路径的Path对象,将其返回到创建时的相同状态。当前点重置为原点

path.computeMetrics TODO

computeMetrics({bool forceClosed = false})有一个可选参数:

  • forceClosed,如果没有使用path.close();,该方法获取的结果isClose将会为false。设置该值为trueisClose将会为true

记录了有关路径轮廓的各种属性

path.moveTo(80, 200);
path.lineTo(320, 400);
path.lineTo(200, 340);
path.lineTo(100, 460);
path.close();
print(path.computeMetrics());
canvas.drawPath(path, paint);
// 打印结果
PathMetric{length: 312.40997314453125, isClosed: false, contourIndex:0}

其中length表示一共绘制的线段长度,isClosed表示路径是否闭合,contourIndex表示等高线指数?

path.transform TODO

drawAtlas TODO

将图像的许多部分( atlas )绘制到画布上

drawRawAtlas TODO

drawImage TODO

drawImageNine TODO

drawImageRect TODO

drawPicture TODO

drawParagraph TODOimage

posted @ 2022-02-27 22:31  菠萝橙子丶  阅读(916)  评论(0编辑  收藏  举报