当前位置: 首页 > news >正文

Flutter canvas 画一条波浪线 进度条

之前用 Flutter Canvas 画过一个三角三角形,html 的 Canvas 也画过一次类似的, 今天用 Flutter Canvas 试了下 感觉差不多:

html 版本

大致效果如下:

思路和 html 实现的类似:

也就是找出点的位置,使用二阶贝塞尔曲线实现:

 代码如下:
import 'package:flutter/material.dart';class PageCanvas extends StatefulWidget {const PageCanvas({Key? key}) : super(key: key);@overrideState<PageCanvas> createState() => _PageCanvasState();
}class _PageCanvasState extends State<PageCanvas> with TickerProviderStateMixin {late Animation<double> animation;late AnimationController controller;@overridevoid initState() {// TODO: implement initStatesuper.initState();controller = AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);animation = Tween<double>(begin: 0, end: 1).animate(controller);controller.repeat();}@overrideWidget build(BuildContext context) {Size size = MediaQuery.of(context).size;return Scaffold(appBar: AppBar(title: const Text('Canvas'),backgroundColor: Colors.blue,),body: Column(children: [AnimatedBuilder(animation: controller,builder: (context, widget) {return CustomPaint(size: Size(size.width, size.height / 3),painter: MyPainter(animation.value),);}),const SizedBox(height: 60,),Center(child: SizedBox(// color: Colors.grey,width: 200,height: 200,child: ClipOval(child: Container(color: Colors.grey.withOpacity(0.3),child: AnimatedBuilder(animation: controller,builder: (context, widget) {return CustomPaint(size: Size(size.width, size.height / 3),painter: MyPainter2(animation.value),);}),),),),)],),);}@overridevoid dispose() {controller.dispose();// TODO: implement disposesuper.dispose();}
}class MyPainter extends CustomPainter {final double value;const MyPainter(this.value);@overridevoid paint(Canvas canvas, Size size) {// print(value);Paint paint = Paint();Path path = Path();double positionX = -size.width * value;double positionY = 100;double positionRange = 10;double positionX2 = -size.width * (1 - value);double positionY2 = 110;double positionRange2 = 20;double positionX3 = -size.width * (1.3 - value);double positionY3 = 120;double positionRange3 = 30;double step = size.width / 4;//path.moveTo(0 + positionX, positionY);for (int i = 1; i < 13; i++) {if (i % 2 == 1) {path.quadraticBezierTo(step * (2 * i - 1) + positionX,positionY - positionRange, step * (2 * i) + positionX, positionY);} else {path.quadraticBezierTo(step * (2 * i - 1) + positionX,positionY + positionRange, step * (2 * i) + positionX, positionY);}}path.lineTo(step * 10, 250);path.lineTo(0, 250);path.close();paint.color = Colors.blue.withOpacity(0.2);canvas.drawPath(path, paint);canvas.save();canvas.restore();path = Path();path.moveTo(0 + positionX2, positionY2);for (int i = 1; i < 13; i++) {if (i % 2 == 1) {path.quadraticBezierTo(step * (2 * i - 1) + positionX2,positionY2 - positionRange2,step * (2 * i) + positionX2,positionY2);} else {path.quadraticBezierTo(step * (2 * i - 1) + positionX2,positionY2 + positionRange2,step * (2 * i) + positionX2,positionY2);}}path.lineTo(step * 10, 250);path.lineTo(0, 250);path.close();paint.color = Colors.blue.withOpacity(0.6);canvas.drawPath(path, paint);canvas.save();canvas.restore();path = Path();path.moveTo(0 + positionX3, positionY3);for (int i = 1; i < 13; i++) {if (i % 2 == 1) {path.quadraticBezierTo(step * (2 * i - 1) + positionX3,positionY3 - positionRange3,step * (2 * i) + positionX3,positionY3);} else {path.quadraticBezierTo(step * (2 * i - 1) + positionX3,positionY3 + positionRange3,step * (2 * i) + positionX3,positionY3);}}path.lineTo(step * 10, 250);path.lineTo(0, 250);path.close();paint.color = Colors.blue;canvas.drawPath(path, paint);}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) {// TODO: implement shouldRepaintreturn oldDelegate != this;//return true;}
}class MyPainter2 extends CustomPainter {final double value;const MyPainter2(this.value);@overridevoid paint(Canvas canvas, Size size) {// print(value);Paint paint = Paint();Path path = Path();double positionX = -size.width * value;double positionY = 50;double positionRange = 10;double positionX2 = -size.width * (1 - value);double positionY2 = 60;double positionRange2 = 20;double positionX3 = -size.width * (1.3 - value);double positionY3 = 70;double positionRange3 = 30;double step = size.width / 4;//path.moveTo(0 + positionX, positionY);for (int i = 1; i < 13; i++) {if (i % 2 == 0) {path.quadraticBezierTo(step * (2 * i - 1) + positionX,positionY - positionRange, step * (2 * i) + positionX, positionY);} else {path.quadraticBezierTo(step * (2 * i - 1) + positionX,positionY + positionRange, step * (2 * i) + positionX, positionY);}}path.lineTo(step * 10, 250);path.lineTo(0, 250);path.close();paint.color = Colors.blue.withOpacity(0.2);canvas.drawPath(path, paint);canvas.save();canvas.restore();path = Path();path.moveTo(0 + positionX2, positionY2);for (int i = 1; i < 13; i++) {if (i % 2 == 0) {path.quadraticBezierTo(step * (2 * i - 1) + positionX2,positionY2 - positionRange2,step * (2 * i) + positionX2,positionY2);} else {path.quadraticBezierTo(step * (2 * i - 1) + positionX2,positionY2 + positionRange2,step * (2 * i) + positionX2,positionY2);}}path.lineTo(step * 10, 250);path.lineTo(0, 250);path.close();paint.color = Colors.blue.withOpacity(0.6);canvas.drawPath(path, paint);canvas.save();canvas.restore();path = Path();path.moveTo(0 + positionX3, positionY3);for (int i = 1; i < 13; i++) {if (i % 2 == 0) {path.quadraticBezierTo(step * (2 * i - 1) + positionX3,positionY3 - positionRange2,step * (2 * i) + positionX3,positionY3);} else {path.quadraticBezierTo(step * (2 * i - 1) + positionX3,positionY3 + positionRange2,step * (2 * i) + positionX3,positionY3);}}path.lineTo(step * 10, 250);path.lineTo(0, 250);path.close();paint.color = Colors.blue;canvas.drawPath(path, paint);canvas.save();canvas.restore();}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) {// TODO: implement shouldRepaintreturn oldDelegate != this;//return true;}
}

http://www.lryc.cn/news/291523.html

相关文章:

  • Java技术栈 —— Spring MVC 与 Spring Boot
  • 跟着cherno手搓游戏引擎【16】Camera和Uniform变量的封装
  • 微服务中间件 RabbitMq学习
  • 3D Gaussian Splatting-实时辐射场渲染技术
  • vue中nextTick()
  • Redis 布隆过滤器
  • 中国的茶文化:现代生活中的茶文化
  • Python正则表达式语法
  • C++核心编程:文件操作 笔记
  • ElementUI组件:Button 按钮
  • #RAG|NLP|Jieba|PDF2WORD# pdf转word-换行问题
  • solr的原理是什么
  • 【安装指南】nodejs下载、安装与配置详细教程
  • Mobileye CES 2024 自动驾驶新技术新方向
  • 【Linux】网络基本配置及网络测试、测试工具
  • pnpm : 无法加载文件 D:\tool\nvm\nvm\node_global\pnpm.ps1,因为在此系统上禁止运行脚本
  • Python 类与实例
  • 2的N次方
  • cobra - 更容易地构建命令行应用
  • windows10设置多个jar后台开机自启
  • 数据库||数据库相关知识练习题目与答案
  • YOLOv8改进 | 损失函数篇 | 更加聚焦的边界框损失Focaler-IoU、InnerFocalerIoU(二次创新)
  • 利用nginx宝塔免费防火墙实现禁止国外IP访问网站
  • 消息中间件(MQ)对比:RabbitMQ、Kafka、ActiveMQ 和 RocketMQ
  • MySQL索引原理以及SQL优化
  • [Bug] [OpenAI] [TypeError: fetch failed] { cause: [Error: AggregateError] }
  • @ 代码随想录算法训练营第5周(C语言)|Day31(贪心算法)
  • 面试手写第二期 Promsie相关
  • Windows冷知识:最小化远程桌面与ffmpeg
  • 12nm工艺,2.5GHz频率,低功耗Cortex-A72处理器培训