Flutter绘制之路径联合详解

来自:网络
时间:2023-07-25
阅读:
目录

前言

Flutter绘制中,path路径可谓是绘制中的核心,理论上,通过path路径可以绘制出任意的二维图形,掌握path路径的绘制,就相当于掌握了绘制的核心,今天介绍一个路径绘制中的基本常用操作,路径联合,将两个path路径通过特定的方式合成为一个新的path路径。

方法

路径联合的核心方法为Path类里的一个静态combine()方法,如下:

// 通过path1和path2路径的到新的路径p
Path path = Path.combine(PathOperation operation, Path path1, Path path2);

方法体有三个入参,分别为联合方式path1path2 ,通过联合方式将path1path2进行联合返回一个新path,具体的联合方式都有哪些呢,那就看下PathOperation这个类。

点进源码发现PathOperation是一个枚举类型,一共有5个类型,也就是有5种联合方式。如下:

enum PathOperation {
  /// 得到path1单独区域 也可理解为path1-path2差集
  difference,
  /// 得到path2单独区域 同理
  reverseDifference,
  /// 得到 path1&path2的交集区域
  intersect,
  /// 得到 path1&path2的补集区域
  xor,
  /// 得到 path1&path2的并集区域
  union,
}

如果path1path2路径有重合的部分,通过以上方式分别可以得到不同的新path

为了直观体现,我们绘制以下两个path路径的圆形,它们之间有重合部分,也有独立的部分。
两个圆环重叠在一起,那么这时候我们就可以通过上面的五种路径联合方式获取到这两个个圆环中的任意交叉的图。

注:通过联合得到的path路径都是一个闭合路径,原始路径如果是非闭合路径,会默认闭合,再进行联合。

Flutter绘制之路径联合详解

上面xor的联合方式再画笔为线条时看不出区别,将画笔设为填充,就发现其实虽然看起来一样,但是路径已经发生改变。

总结下5种联合方式:2个取单独自己的,2个分别取相同的部分和不同的部分,1个我全都要。

其实通过这5种联合功能,我们就可以轻松的绘制出一些比较复杂的图形,比如下面的例子:

太极

太极图正常可以用贝塞尔曲线或弧线绘制,但是通过路径联合方式就会变得非常简单,只需要绘制圆和矩形就行了。

首先我们绘制一个黑色圆,

Flutter绘制之路径联合详解

其次利用矩形区域和圆进行路径联合得到半圆区域填充白色,

Flutter绘制之路径联合详解

最后再绘制两个小圆,添加两个太极眼,完成。

Flutter绘制之路径联合详解

只需简单的三步我们就画出了太极图,并且使用的都是现成的基础几何图形。

核心代码:

// 大圆直径
 double r = 200;
 Path pathA = Path();
 pathA.addOval(Rect.fromCenter(center: Offset.zero, width: r, height: r));
// 黑白小圆
 Path pathB = Path();
 pathB.addOval(Rect.fromCenter(center: Offset(0, r / 4), width: r / 2, height: r / 2));
 Path pathC = Path();
 pathC.addOval(Rect.fromCenter(center: Offset(0, -r / 4), width: r / 2, height: r / 2));
 // 辅助路径
 Path pathD = Path();
 pathD.addRect(Rect.fromCenter(center: Offset(r / 4, 0), width: r / 2, height: r));
 canvas.drawPath(pathA, paint
       ..color = Colors.black
       ..style = PaintingStyle.fill);
 canvas.drawPath(Path.combine(PathOperation.intersect, pathA, pathD), paint..color = Colors.white);
 canvas.drawPath(pathC, paint..color = Colors.white);
 canvas.drawPath(pathB, paint..color = Colors.black);
 // 太极眼
 canvas.drawOval(
     Rect.fromCenter(center: Offset(0, r / 4), width: r / 20, height: r / 20), paint..color = Colors.white);
 canvas.drawOval(
     Rect.fromCenter(center: Offset(0, -r / 4), width: r / 20, height: r / 20), paint..color = Colors.black);

天狗食月

还可以利用路径联合配合动画实现月圆月缺变化情况,背景利用随机数生成随机坐标绘制一些星星,多角形的绘制有兴趣可以看下之前这篇文章 Flutter实现一个多边形or多角星组件

Flutter绘制之路径联合详解

将圆形进行位移重合,达到天狗食月的效果,代码就不贴了。

总结

路径联合一共有5种方式,虽然只有5种,但是这5种方式其实已经涵盖了两个图形的任意可能会出现的区域,熟练掌握路径联合方式,对于一些复杂的图形我们就可以通过联合方式巧妙的生成,希望对正在阅读的你在Flutter绘制中有所帮助 ~

返回顶部
顶部