【CustomPainter】渐变圆环

说明

实现一个渐变圆环,起点位置为- π / 2

效果

在这里插入图片描述

源码

  • GradientCircularPainter1
class GradientCircularPainter1 extends CustomPainter {final double progress;GradientCircularPainter1(this.progress);void paint(Canvas canvas, Size size) {const double strokeWidth = 8;final center = size.center(Offset.zero);final radius = (size.width - 2 * strokeWidth) / 2;// 整个圆环的背景色:绘制灰色圆环填充剩余部分final bgPaint = Paint()..color = Colors.grey.withOpacity(0.2)..style = PaintingStyle.stroke..strokeWidth = strokeWidth;canvas.drawArc(Rect.fromCircle(center: center, radius: radius),0.0,2 * pi,false,bgPaint,);// 渐变进度条final rect = Offset.zero & size;const gradient =SweepGradient(colors: [Color(0xff40A9FD), Color(0xFF7451FF)]);final paint = Paint()..shader = gradient.createShader(rect)..style = PaintingStyle.stroke..strokeWidth = strokeWidth;const startAngle = -pi / 2;final sweepAngle = (2 * pi) * progress;canvas.drawArc(Rect.fromCircle(center: center, radius: radius),startAngle,sweepAngle,false,paint,);}bool shouldRepaint(GradientCircularPainter1 oldDelegate) {return progress != oldDelegate.progress;}
}
  • GradientCircularPainter2
class GradientCircularPainter2 extends CustomPainter {final double progress;GradientCircularPainter2(this.progress);void paint(Canvas canvas, Size size) {const double strokeWidth = 8;final center = size.center(Offset.zero);final radius = (size.width - 2 * strokeWidth) / 2;// 整个圆环的背景色:绘制灰色圆环填充剩余部分final bgPaint = Paint()..color = Colors.grey.withOpacity(0.2)..style = PaintingStyle.stroke..strokeWidth = strokeWidth;canvas.drawArc(Rect.fromCircle(center: center, radius: radius),0.0,2 * pi,false,bgPaint,);// 渐变进度条final rect = Offset.zero & size;const gradient =SweepGradient(colors: [Color(0xff40A9FD), Color(0xFF7451FF)]);final paint = Paint()..shader = gradient.createShader(rect)..style = PaintingStyle.stroke..strokeWidth = strokeWidth;// 💡关键:画布逆时针旋转90度canvas.save();canvas.translate(center.dx, center.dy);canvas.rotate(-pi / 2);canvas.translate(-center.dx, -center.dy);const startAngle = 0.0;final sweepAngle = (2 * pi) * progress;canvas.drawArc(Rect.fromCircle(center: center, radius: radius),startAngle,sweepAngle,false,paint,);canvas.restore();}bool shouldRepaint(GradientCircularPainter2 oldDelegate) =>progress != oldDelegate.progress;
}
  • GradientCircularPainter3
class GradientCircularPainter3 extends CustomPainter {final double progress;GradientCircularPainter3(this.progress);void paint(Canvas canvas, Size size) {const double strokeWidth = 8;final center = size.center(Offset.zero);final radius = (size.width - 2 * strokeWidth) / 2;// 整个圆环的背景色:绘制灰色圆环填充剩余部分final bgPaint = Paint()..color = Colors.grey.withOpacity(0.2)..style = PaintingStyle.stroke..strokeWidth = strokeWidth;canvas.drawArc(Rect.fromCircle(center: center, radius: radius),0.0,2 * pi,false,bgPaint,);// 渐变进度条final rect = Offset.zero & size;// 💡关键:首尾颜色一致,更改stopsconst gradient = SweepGradient(colors: [Color(0xff40A9FD), Color(0xFF7451FF), Color(0xff40A9FD)],stops: [0.0, 0.5, 0.7],tileMode: TileMode.clamp);final paint = Paint()..shader = gradient.createShader(rect)..style = PaintingStyle.stroke..strokeWidth = strokeWidth;const startAngle = -pi / 2;final sweepAngle = (2 * pi) * progress;canvas.drawArc(Rect.fromCircle(center: center, radius: radius),startAngle,sweepAngle,false,paint,);}bool shouldRepaint(GradientCircularPainter3 oldDelegate) {return progress != oldDelegate.progress;}
}
  • UI渲染
Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const SizedBox(height: 20,),// 不是想要的渐变效果CustomPaint(size: const Size(60, 60),painter: GradientCircularPainter1(0.8),),const SizedBox(height: 20,),// 可取CustomPaint(size: const Size(60, 60),painter: GradientCircularPainter2(0.8),),const SizedBox(height: 20,),// 可取CustomPaint(size: const Size(60, 60),painter: GradientCircularPainter3(0.8),),],),)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145310.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

VCNet论文阅读笔记

VCNet论文阅读笔记 0、基本信息 信息细节英文题目VCNet and Functional Targeted Regularization For Learning Causal Effects of Continuous Treatments翻译VCNet和功能目标正则化用于学习连续处理的因果效应单位芝加哥大学年份2021论文链接[2103.07861] VCNet和功能定向正…

OpenCV特征检测(5)检测图像中的角点函数cornerMinEigenVal()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算用于角点检测的梯度矩阵的最小特征值。 该函数类似于 cornerEigenValsAndVecs,但它计算并存储协方差矩阵导数的最小特征值&…

2024上海工博会,正运动激光振镜运动控制器应用预览(二)

■展会名称: 第二十四届中国国际工业博览会(以下简称“上海工博会”) ■展会日期 2024年9月24日–28日 ■展馆地点 中国国家会展中心(上海) ■展位号 6.1H-E261 正运动激光加工控制解决方案主要分为激光振镜运动…

24 小时不关机的挂机云电脑,还能这么玩?

云电脑技术为我们提供了无限可能。特别是对于游戏爱好者,挂机云电脑不仅解决了传统电脑的局限性,还带来了更为便利的游戏体验。除此之外云电脑还有什么其他玩法呢? 01 挂机云电脑的优势 首先要知道,什么是挂机云电脑&#xff1f…

解锁自动化新境界:KeymouseGo,让键盘和鼠标动起来!

文章目录 解锁自动化新境界:KeymouseGo,让键盘和鼠标动起来!背景:为何选择KeymouseGo?KeymouseGo简介安装KeymouseGo简单函数使用应用场景常见问题与解决方案总结 解锁自动化新境界:KeymouseGo,…

操作系统 | 学习笔记 | | 王道 | 5.1 I/O管理概述

5.1 I/O管理概述 5.1.1 I/O设备 注:块设备可以寻址,但是字符设备是不可寻址的 I/O设备是将数据输入到计算机中,或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部件; 设备的分类 按使用特性分类&#xff…

from tqdm.auto import tqdm用法详细介绍

tqdm 是一个 Python 库,用于在长时间运行的任务中显示进度条。tqdm.auto 是 tqdm 的一个版本,能够自动适配输出环境(如 Jupyter Notebook、命令行等),以确保进度条在各种环境下显示正确。下面是 tqdm.auto 的详细用法介…

英飞凌 PSoC6 评估板 RT-Thread 开发环境搭建

本文介绍如何搭建基于 RT-Thread Studio IDE 工具的 PSoC6 RTT 评估板的开发环境,通过搭建一个简单的工程,将代码编译、下载到 PSoC6 RTT 开发板。 安装软件包 首先需要安装 RT-Thread Studio,如果你还没安装,可以点击这里下载安…

MySQL 中的 UTF-8 与 UTF8MB4:差异解析

在 MySQL 数据库中,字符集的选择对于数据的存储和处理至关重要。其中,UTF-8 和 UTF8MB4 是两个常见的字符集选项。那么,它们之间到底有什么区别呢? 一、字符集简介 UTF-8 UTF-8(8-bit Unicode Transformation Format&…

中伟视界:AI边端云一体化管控平台的特色功能介绍及其工作原理

在当前的数字化浪潮中,人工智能(AI)与物联网(IoT)技术逐渐渗透到各行各业,而如何在复杂、多层次的技术环境中高效管理和控制这些系统,成为了企业追求自动化、智能化发展的关键挑战。为了满足这种…

docker-compose up 报错:KeyError: ‘ContainerConfig‘

使用命令查看所有容器: docker ps -a 找到有异常的容器删除 docker rm {容器id} 后续发现还是会出现这种情况,尝试使用更高版本的docker-compose后解决

Java开发-面试题-0035-Spring代理方式有哪些

Java开发-面试题-0035-Spring代理方式有哪些 更多内容欢迎关注我(持续更新中,欢迎Star✨) Github:CodeZeng1998/Java-Developer-Work-Note (技术)微信公众号:CodeZeng1998 (生活&…

【Python报错已解决】SyntaxError invalid syntax

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

怎么解除BitLocker对磁盘的加密?

BitLocker是一种Windows操作系统内置的加密功能,用于保护用户的数据安全。它通过对整个磁盘进行加密,防止数据被未经授权的用户访问。BitLocker主要用于保护笔记本电脑和台式机中的重要数据,尤其是在设备丢失或被盗的情况下。怎么解除BitLock…

【Redis入门到精通二】Redis核心数据类型(String,Hash)详解

目录 Redis数据类型 1.String类型 (1)常见命令 (2)内部编码 2.Hash类型 (1)常见命令 (2)内部编码 Redis数据类型 查阅Redis官方文档可知,Redis提供给用户的核心数据…

Redhat 7,8,9系(复刻系列) 一键部署Oracle19c rpm

Oracle19c前言 Oracle 19c 是甲骨文公司推出的一款企业级关系数据库管理系统,它带来了许多新的功能和改进,使得数据库管理更加高效、安全和可靠。以下是关于 Oracle 19c 的详细介绍: 主要新特性 多租户架构:支持多租户架构,允许多个独立的数据库实例在同一个物理服务器上…

鸿蒙开发之ArkUI 界面篇 十四 个人中心导航界面

鸿蒙要实现如图效果,代码简洁到令人难以置信: 整体布局是水平方向的,用row容器,左边是Image加载图标,中间是Text。右边也是Image加载图片,主轴子组件之间的距离用justifyContent(FlexAlign.SpaceBetween)&a…

MySQL 中的锁定粒度:理解与应用

在 MySQL 数据库的使用中,锁定粒度是一个至关重要的概念。它决定了数据库在并发控制中锁定的范围和程度,对数据库的性能和并发能力有着深远的影响。今天,我们就来深入了解一下 MySQL 中的锁定粒度是什么意思,并通过实际案例来更好…

C++自动寻径算法

测试 #include <iostream> #include "source/AStar.hpp"int main() {AStar::Generator generator;generator.setWorldSize({25, 25});generator.setHeuristic(AStar::Heuristic::euclidean);generator.setDiagonalMovement(true);generator.addCollision({1, …

如何搭建客户服务知识库?五项基本方法让你业务增长100%

在竞争激烈的市场环境中&#xff0c;优质的客户服务已成为企业脱颖而出的关键。而一个高效、全面的客户服务知识库&#xff0c;不仅能够提升客户满意度&#xff0c;还能显著降低客服团队的工作负担&#xff0c;促进业务的稳健增长。本文将介绍五项基本方法&#xff0c;帮助你搭…