前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >flutter 路径的用法

flutter 路径的用法

作者头像
用户1974410
发布2022-09-20 16:43:20
7930
发布2022-09-20 16:43:20
举报
文章被收录于专栏:flutter开发精选
本节目标:

代码语言:javascript
复制
[1]. 了解如何通过移动路径形成形状:直线移动、圆弧移动、圆锥曲线移动、贝塞尔曲线移动。
[2]. 了解路径的 [绝对移动] 和 [相对移动]。
[3]. 了解在已有的路径中添加其他形状:添加矩形、圆角矩形、椭圆、圆弧、多边形、其他路径。
[4]. 使用 path 绘制坐标系。

一、路径加入方法

下图是路径形成的基础方法,包括路径的移动、加入直线圆弧圆锥曲线贝塞尔曲线。 对这些 API 的掌握程度,直接决定你运用路径的能力。


1.moveTolineTo: 画线

下面画布已经移动到屏幕中心,并且 y轴向正下方。想象一下,你现在手里拿着一只笔。 moveTo相当于提起笔落到纸上的位置坐标,且坐标以画布原点为参考系lineTo相当于从落笔点画直线到期望的坐标点,且坐标以画布原点为参考系

代码语言:javascript
复制
---->[p05_path/01_moveTo_lineTo/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.deepPurpleAccent
  ..style = PaintingStyle.fill;
path
  ..moveTo(0, 0) //移至(0,0)点
  ..lineTo(60, 80) //从(0,0)画线到(60, 80) 点
  ..lineTo(60, 0) //从(60,80)画线到(60, 0) 点
  ..lineTo(0, -80) //从(60, 0) 画线到(0, -80)点
  ..close(); //闭合路径
canvas.drawPath(path, paint);

paint
  ..style = PaintingStyle.stroke
  ..strokeWidth = 2;
path
  ..moveTo(0, 0)
  ..lineTo(-60, 80)
  ..lineTo(-60, 0)
  ..lineTo(0, -80);
canvas.drawPath(path, paint);

2.relativeMoveTorelativeLineTo: 相对画线

如果点位已经知道,使用 moveTo 和 lineTo 会比较方便,但很多情况下是不能直接知道的。 比如在某点的基础上,画一条线,要求左移 10,上移 60,这样点位很难直接确定。 使用 relative 系列方法就会非常简单。如下图形的路径绘制,不用相对坐标会很复杂。 使用相对的坐标会更方便调整(左侧只需移动起始点即可全部移动)

代码语言:javascript
复制
---->[p05_path/02_relativeMoveTo_relativeLineTo/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.green
  ..style = PaintingStyle.fill;
path
  ..relativeMoveTo(0, 0)
  ..relativeLineTo(100, 120)
  ..relativeLineTo(-10, -60)
  ..relativeLineTo( 60,-10,)
  ..close();
canvas.drawPath(path, paint);

path.reset();
paint
  ..style = PaintingStyle.stroke..color=Colors.green
  ..strokeWidth = 2;
path
  ..relativeMoveTo(-200, 0)
  ..relativeLineTo(100, 120)
  ..relativeLineTo(-10, -60)
  ..relativeLineTo( 60,-10,)..close();
canvas.drawPath(path, paint);

3.arcTo: 圆弧

arcTo 用于圆弧路径,指定一个矩形域,形成椭圆。 指定起始弧度,和扫描弧度,就可以从椭圆上截取出圆弧。 最后一参代表是否强行移动,如果为true,如图左,绘制圆弧时会先移动到起点

代码语言:javascript
复制
---->[p05_path/03_arcTo/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;

// 绘制左侧
var rect = Rect.fromCenter(center: Offset(0, 0), width: 160, height: 100);
path.lineTo(30, 30);
path..arcTo(rect, 0, pi * 1.5, true);
canvas.drawPath(path, paint);

path.reset();
canvas.translate(200, 0);
// 绘制右侧
path.lineTo(30, 30);
path..arcTo(rect, 0, pi * 1.5, false);
canvas.drawPath(path, paint);

4.arcToPointrelativeArcToPoint: 点定弧

当想要画圆弧到某个点,用 arcToPoint 会非常方便 接受一个点位入参 Offset,是圆弧的终点,可指定圆弧半径radius、是否使用优弧、是否顺时针 左侧: 使用优弧: largeArc: true ,逆时针:clockwise: false 中间: 使用劣弧: largeArc: false ,顺时针:clockwise: true 右侧: 使用优弧: largeArc: true ,顺时针:clockwise: true

代码语言:javascript
复制
---->[p05_path/04_arcToPoint_relativeArcToPoint/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;
path.lineTo(80, -40);

//绘制中间
path..arcToPoint(
  Offset(40, 40),
  radius: Radius.circular(60),
  largeArc: false,
)..close();
canvas.drawPath(path, paint);

path.reset();
canvas.translate(-150, 0);
//绘制左侧
path.lineTo(80, -40);
path..arcToPoint(
    Offset(40, 40),
    radius: Radius.circular(60),
    largeArc: true,
    clockwise: false
)..close();
canvas.drawPath(path, paint);

path.reset();
canvas.translate(150+150.0, 0);
//绘制右侧
path.lineTo(80, -40);
path..arcToPoint(
  Offset(40, 40),
  radius: Radius.circular(60),
  largeArc: true,
)..close();
canvas.drawPath(path, paint);

relativeArcToPoint方法即使用相对位置来加入圆弧路径,参数含义与上面一致。


5.conicTorelativeConicTo: 圆锥曲线

conicTo 接收五个参数用于绘制圆锥曲线,包括椭圆线抛物线双曲线 其中前两参是控制点,三四参是结束点,第五参是权重。(下图已画出辅助点) 当权重< 1 时,圆锥曲线是椭圆线,如下左图 当权重= 1 时,圆锥曲线是抛物线,如下中图 当权重> 1 时,圆锥曲线是双曲线,如下右图

代码语言:javascript
复制
---->[p05_path/05_conicTo_relativeConicTo/paper.dart]----
final Offset p1 = Offset(80, -100);
final Offset p2 = Offset(160, 0);

Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;

//抛物线
path.conicTo(p1.dx, p1.dy, p2.dx, p2.dy, 1);
canvas.drawPath(path, paint);

path.reset();
canvas.translate(-180, 0);
//椭圆线
path.conicTo(p1.dx, p1.dy, p2.dx, p2.dy, 0.5);
canvas.drawPath(path, paint);

path.reset();
canvas.translate(180+180.0, 0);
//双曲线
path.conicTo(p1.dx, p1.dy, p2.dx, p2.dy, 1.5);
canvas.drawPath(path, paint);

relativeConicTo方法即使用相对位置来加入圆锥曲线路径,参数含义与上面一致。


6.quadraticBezierTorelativeQuadraticBezierTo: 二阶贝塞尔

quadraticBezierTo接收四个参数用于绘制二阶贝塞尔曲线。 其中前两参是控制点,三四参是结束点。(下图已画出蓝色辅助点线) relativeQuadraticBezierTo是在使用相对位置来加入二阶贝塞尔曲线路径。 注: 贝塞尔曲线,在后面章节会有专题讲解,此处只是简单介绍。

代码语言:javascript
复制
---->[p05_path/06_quadraticBezier/paper.dart]----
final Offset p1 = Offset(100, -100);
final Offset p2 = Offset(160, 50);

Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;
path.quadraticBezierTo(p1.dx, p1.dy, p2.dx, p2.dy);
path.relativeQuadraticBezierTo(p1.dx, p1.dy, p2.dx, p2.dy);
canvas.drawPath(path, paint);

7.cubicTorelativeCubicTo: 三阶贝塞尔

quadraticBezierTo接收六个参数用于绘制三阶贝塞尔曲线 其中前两参是控制点1,三四参是控制点2,五六参是结束点。(下图已画出蓝色辅助点线) relativeCubicTo是在使用相对位置来加入三阶贝塞尔曲线路径。

代码语言:javascript
复制
---->[p05_path/07_cubicTo/paper.dart]----
Path path = Path();
Paint paint = Paint();
paint
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;
path.cubicTo(p1.dx, p1.dy, p2.dx, p2.dy, p3.dx, p3.dy);

path.relativeCubicTo(p1.dx, p1.dy, p2.dx, p2.dy, p3.dx, p3.dy);
canvas.drawPath(path, paint);

二、为路径添加已有形状

可以在已知路径上添加矩形圆角矩形椭圆圆弧多边形路径


1. addRectaddRRect: 添加类矩形

addRect用于在已有路径上添加矩形路径,接受一个Rect对象addRRect用于在已有路径上添加圆角矩形路径,接受一个RRect对象

代码语言:javascript
复制
---->[p05_path/08_addRect_addRRect/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;

Rect rect = Rect.fromPoints(Offset(100, 100), Offset(160, 160));
path
  ..lineTo(100, 100)
  ..addRect(rect)
  ..relativeLineTo(100, -100)
  ..addRRect(RRect.fromRectXY(rect.translate(100, -100), 10, 10));
canvas.drawPath(path, paint);

2. addOvaladdArc: 添加类圆形

addOval用于在已有路径上添加椭圆路径,接受一个Rect 对象addArc用于在已有路径上添加圆弧路径,接受一个Rect 对象,起始弧度、扫描弧度

代码语言:javascript
复制
---->[p05_path/09_addOval_addArc/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;

Rect rect = Rect.fromPoints(Offset(100, 100), Offset(160, 140));
path
  ..lineTo(100, 100)
  ..addOval(rect)
  ..relativeLineTo(100, -100)
  ..addArc(rect.translate(100 + 60.0, -100), 0, pi);
canvas.drawPath(path, paint);

3. addPolygon: 添加多边形路径 、addPath:添加路径

addPolygon用于在已有路径上添加多边形路径,接受一个List<Offset>对象addPath用于在已有路径上添加路径,接受一个Path对象和偏移量Offset

代码语言:javascript
复制
---->[p04_path/10_addPolygon/paper.dart]----
Path path = Path();
Paint paint = Paint()
  ..color = Colors.purpleAccent
  ..strokeWidth = 2
  ..style = PaintingStyle.stroke;
var p0 = Offset(100, 100);
path
  ..lineTo(100, 100)
  ..addPolygon([
    p0,
    p0.translate(20, -20),
    p0.translate(40, -20),
    p0.translate(60, 0),
    p0.translate(60, 20),
    p0.translate(40, 40),
    p0.translate(20, 40),
    p0.translate(0, 20),
  ], true)
  ..addPath(
      Path()..relativeQuadraticBezierTo(125, -100, 260, 0), Offset.zero)
  ..lineTo(160, 100);
canvas.drawPath(path, paint);

三、使用 Path 实现网格坐标系

前面已经用过 Canvas 绘线的方式实现了网格坐标系,那为什么还要用 Path 再做一遍呢? 用 Canvas 绘线要画很多次,还伴随 Canvas 的移动。而 Path 则是收集路径,一次画完。 这样无论从性能方面还是代码简洁性方面都比之前好。绘线路径如下:


Screenshot_1604132871

代码语言:javascript
复制
---->[p05_path/11_path_coo/coordinate.dart]----
void _drawGridLine(Canvas canvas, Size size) {
  _gridPaint
    ..style = PaintingStyle.stroke
    ..strokeWidth = .5
    ..color = Colors.grey;
  
  for (int i = 0; i < size.width / 2 / step; i++) {
    _gridPath.moveTo(step * i, -size.height / 2 );
    _gridPath.relativeLineTo(0, size.height);
    _gridPath.moveTo(-step * i, -size.height / 2 );
    _gridPath.relativeLineTo(0, size.height);
  }
  
  for (int i = 0; i < size.height / 2 / step; i++) {
    _gridPath.moveTo(-size.width / 2,step * i );
    _gridPath.relativeLineTo(size.width,0 );
    _gridPath.moveTo(-size.width / 2,-step * i,  );
    _gridPath.relativeLineTo(size.width,0 );
  }
  canvas.drawPath(_gridPath, _gridPaint);
}

另外,我将绘制坐标系的逻辑封装到了Coordinate类中,方便以后的使用。比如今后想要绘制一个坐标系,只需要两步,在之后的示例中将使用这个坐标系。

代码语言:javascript
复制
class PaperPainter extends CustomPainter {
  final Coordinate coordinate = Coordinate(step: 25); // 定义坐标系
  
  @override
  void paint(Canvas canvas, Size size) {
    coordinate.paint(canvas, size); // 绘制坐标系
  }

  @override
  bool shouldRepaint(PaperPainter oldDelegate) => false;
}

到这里,基本的路径添加操作就介绍完了,下一节将介绍路径的操作方法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 flutter开发精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本节目标:
  • 一、路径加入方法
    • 1.moveTo和lineTo: 画线
      • 2.relativeMoveTo和relativeLineTo: 相对画线
        • 3.arcTo: 圆弧
          • 4.arcToPoint和relativeArcToPoint: 点定弧
            • 5.conicTo和relativeConicTo: 圆锥曲线
              • 6.quadraticBezierTo和relativeQuadraticBezierTo: 二阶贝塞尔
                • 7.cubicTo和relativeCubicTo: 三阶贝塞尔
                • 二、为路径添加已有形状
                  • 1. addRect和addRRect: 添加类矩形
                    • 2. addOval和addArc: 添加类圆形
                      • 3. addPolygon: 添加多边形路径 、addPath:添加路径
                        • 三、使用 Path 实现网格坐标系
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档