# 【Flutter 专题】84 图解自定义 ACEWave 波浪 Widget (二)

### 1. 区分波浪宽度动画

```return Transform.translate(
offset: Offset(waveWidth * _curvedAnimation.value, 0.0),
child: Container(); // 波浪```

### 2. 填充波浪颜色

```Path _wavePath(path, size, plusWidth) {
for (int i = 0; i < _count; i++) {
path.moveTo(waveWidth * i - size.width - startOffset, startOffsetY);
_quaterWidth + waveWidth * i - size.width - startOffset, startOffsetY - waveHeight,
_quaterWidth * 2 + waveWidth * i - size.width - startOffset, startOffsetY);
path.moveTo(_quaterWidth * 2 + waveWidth * i - size.width - startOffset, startOffsetY);
_quaterWidth * 3 + waveWidth * i - size.width - startOffset, startOffsetY + waveHeight,
_quaterWidth * 4 + waveWidth * i - size.width - startOffset, startOffsetY);
path.moveTo(_quaterWidth * 4 + waveWidth * i - size.width - startOffset, startOffsetY);
}
path.lineTo(_quaterWidth * 4 + waveWidth * (_count - 1) - size.width - startOffset, 600.0);
path.lineTo(-size.width - startOffset, 600.0);
path.lineTo(-size.width - startOffset, startOffsetY);

for (int i = 0; i < _count; i++) {
path.moveTo(waveWidth * i - startOffset + plusWidth, startOffsetY);
_quaterWidth + waveWidth * i - startOffset + plusWidth, startOffsetY - waveHeight,
_quaterWidth * 2 + waveWidth * i - startOffset + plusWidth, startOffsetY);
path.moveTo(_quaterWidth * 2 + waveWidth * i - startOffset + plusWidth, startOffsetY);
_quaterWidth * 3 + waveWidth * i - startOffset + plusWidth, startOffsetY + waveHeight,
_quaterWidth * 4 + waveWidth * i - startOffset + plusWidth, startOffsetY);
path.moveTo(_quaterWidth * 4 + waveWidth * i - startOffset + plusWidth, startOffsetY);
}
path.lineTo(_quaterWidth * 4 + waveWidth * (_count - 1) - startOffset + plusWidth, 600.0);
path.lineTo(-startOffset + plusWidth, 600.0);
path.lineTo(-startOffset + plusWidth, startOffsetY);

for (int i = 0; i < _count; i++) {
path.moveTo(waveWidth * i + size.width - startOffset + plusWidth * 2, startOffsetY);
_quaterWidth + waveWidth * i + size.width - startOffset + plusWidth * 2, startOffsetY - waveHeight,
_quaterWidth * 2 + waveWidth * i + size.width - startOffset + plusWidth * 2, startOffsetY);
path.moveTo(
_quaterWidth * 2 + waveWidth * i + size.width - startOffset + plusWidth * 2, startOffsetY);
_quaterWidth * 3 + waveWidth * i + size.width - startOffset + plusWidth * 2,
startOffsetY + waveHeight, _quaterWidth * 4 + waveWidth * i + size.width - startOffset + plusWidth * 2, startOffsetY);
path.moveTo(_quaterWidth * 4 + waveWidth * i + size.width - startOffset + plusWidth * 2, startOffsetY);
}
path.lineTo(
_quaterWidth * 4 + waveWidth * (_count - 1) + size.width - startOffset + plusWidth * 2, 600.0);
path.lineTo(size.width - startOffset + plusWidth * 2, 600.0);
path.lineTo(size.width - startOffset + plusWidth * 2, startOffsetY);
return path;
}```

### 3. 波浪渐变色

```Paint paint = Paint()
..color = Colors.blue ..strokeCap = StrokeCap.round ..strokeWidth = 6
..style = PaintingStyle.fill;
var rect = Offset(0.0, startOffsetY) & Size(size.width, size.height)
begin: Alignment.bottomCenter,
end: Alignment.topCenter,

### 4. 裁剪波浪

```canvas.save();

canvas.clipPath(_clipPath(size, _plusWidth));
canvas.drawPath(_wavePath(size, _plusWidth), paint);

canvas.restore();```

### 5. 设置多条波浪

```// 波浪整体高度(裁剪后)
final double allHeight;
// 一个周期波浪宽度 List
final List<double> waveWidthList;
// 波峰到中心点高度 List
final List<double> waveHeightList;
// 水平偏移量 List
final List<double> startOffsetXList;
// 波峰距顶点偏移量 List
final List<double> startOffsetYList;
// 时间 List
final List<Duration> durationList;
// 渐变色 List
final List<List<Color>> waveColorList;

ACEWave(this.waveWidthList, this.waveHeightList, this.allHeight,
{this.durationList,
this.startOffsetXList,
this.startOffsetYList,
this.waveColorList});```
```List<double> waveWidth = [600, 800, 300];
List<double> waveHeight = [60, 80, 70];
List<double> startOffsetX = [30, 150, 100];
List<double> startOffsetY = [100, 120, 100];
List<Duration> duration = [
Duration(milliseconds: 6000),
Duration(milliseconds: 4000),
Duration(milliseconds: 5000)
];
List<List<Color>> colorList = [
[Colors.green.withOpacity(0.2), Colors.white.withOpacity(0.4)],
[Colors.blue.withOpacity(0.2), Colors.white.withOpacity(0.4)],
[Colors.blue.withOpacity(0.2), Colors.white.withOpacity(0.4)]
];
return Scaffold(
appBar: AppBar(title: Text('ACEWave Page')),
body: Container(
color: Colors.grey,
height: (MediaQuery.of(context).size.height),
child: Container(
child: ACEWave(
waveWidth,
waveHeight,
300.0,
startOffsetXList: startOffsetX,
startOffsetYList: startOffsetY,
durationList: duration,
waveColorList: colorList,
))));```

ACEWave 案例源码

0 条评论

• ### 【Flutter 专题】76 图解基本 TabBar 标签导航栏 (二)

和尚刚刚学习了 TabBar 标签导航栏的使用，其中对于标签指示器 indicator 的使用较少；和尚今天尝试一下自定义标签指示器；

• ### 【Flutter 专题】83 图解自定义 ACEWave 波浪 Widget (一)

和尚今天尝试一下绘制波浪的效果，虽然 pub 仓库中已经有成熟的插件，但和尚还是准备用之前学习的 Canvas 和 Animation 尝试自定义一个 ACEW...

• ### 【Flutter 专题】29 易忽略的【小而巧】的技术点汇总 (五)

和尚在做 Android 时经常会双击快速点击返回键弹出退出对话框，之后在进行操作，而 Flutter 也提供了监听返回导航的 WillPopSco...

• ### 奇怪，Spring Security 登录成功后总是获取不到登录用户信息？

一开始我觉得这可能是一个小概率 BUG，但是当问的人多了，我觉得这个问题对于新手来说还有一定的普遍性，有必要来写篇文章跟大家仔细聊一聊这个问题，防止小伙伴们掉坑...

• ### AI时代，如何缓解CMO的决策焦虑？

2018 是人工智能落地之年，在 AI 应用方面，目前中国已呈现出爆发的趋势，主要集中在安防、金融、医疗、教育、零售、机器人以及智能驾驶等领域。

• ### C语言 | 每日基础（78）

读者：怎样才能进行反向操作, 把 struct tm 或一个字符串转换成 time_t？

• ### matplotlib基础绘图命令之violinplot

vert参数的默认值为True，表示竖直方向的小提琴图，当取值WieFalse时，绘制水平方向的小提琴图，用法如下

• ### 用matplotlib实现画中画

当我们想要在一个坐标系中包含另外一个完整的图像时，就需要用到子图相关的技术，在matplotlib中，提供了以下两种实现方式

• ### 学界 | 人工智能的圣杯：关于可解释AI(XAI)的一切

这期间，在企业客户却也始终存在一种怀疑态度：AI系统做出的产品部署是否真的值得被信赖呢？