Flutter开发进阶之Canvas

Flutter开发进阶之Canvas

在Flutter开发中Canvas作为一个绘制2D图形的工具,提供了一系列绘图方法,可以用来绘制各种形状、线条、文本和图像等;
Canvas对象是作为CustomPainter的子组件进行构建的;

void paint(Canvas canvas, Size size);

Flutter开发

一、绘制的保存和恢复

Canvas通过使用以下方法调用原生层(C++)的绘图操作;

factory Canvas(PictureRecorder recorder, [ Rect? cullRect ]) = _NativeCanvas;

通过以下方法保存上下文和恢复;

void save();
void saveLayer(Rect? bounds, Paint paint);void restore();
void restoreToCount(int count);
/// 保存数量
int getSaveCount();

二、绘制的变换

添加平移变换,分别在x轴和轴上;

void translate(double dx, double dy);

添加对应轴的缩放变换,若不指定sy则x轴和y轴都等比例缩放sx;

void scale(double sx, [double? sy]);

根据radians的弧度进行旋转变换;

void rotate(double radians);

相对原始角度对应的百分比倾斜变换;

void skew(double sx, double sy);

变换4x4矩阵;

void transform(Float64List matrix4);

变换的获取;

Float64List getTransform();

三、绘制的渲染流水线

还可以按指定规则进行裁剪;

void clipRect(Rect rect, { ClipOp clipOp = ClipOp.intersect, bool doAntiAlias = true });
void clipRRect(RRect rrect, {bool doAntiAlias = true});
void clipPath(Path path, {bool doAntiAlias = true});/// 获取裁剪的边界
Rect getLocalClipBounds();
Rect getDestinationClipBounds();

通过以下API进行形状图元的组合、着色;

/// 着色
void drawColor(Color color, BlendMode blendMode);
/// 通过画笔进行点对点划线
void drawLine(Offset p1, Offset p2, Paint paint);
/// 画笔填充
void drawPaint(Paint paint);
/// 绘制矩形
void drawRect(Rect rect, Paint paint);
/// 绘制圆角矩形
void drawRRect(RRect rrect, Paint paint);
/// 绘制两个圆角矩形之差,填充或描边由画笔决定
void drawDRRect(RRect outer, RRect inner, Paint paint);
/// 绘制椭圆
void drawOval(Rect rect, Paint paint);
/// 绘制圆
void drawCircle(Offset c, double radius, Paint paint);
/// 绘制圆弧
void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint);
/// 根据path绘制,一般是组合图形
void drawPath(Path path, Paint paint);
/// 给定位置绘制图片
void drawImage(Image image, Offset offset, Paint paint);
void drawImageRect(Image image, Rect src, Rect dst, Paint paint);
/// 图像分割成3x3绘制
void drawImageNine(Image image, Rect center, Rect dst, Paint paint);
/// 绘制图片
void drawPicture(Picture picture);
/// 给定位置的文本绘制
void drawParagraph(Paragraph paragraph, Offset offset);
/// 绘制点序列
void drawPoints(PointMode pointMode, List<Offset> points, Paint paint);
void drawRawPoints(PointMode pointMode, Float32List points, Paint paint);
/// 绘制顶点
void drawVertices(Vertices vertices, BlendMode blendMode, Paint paint);
/// 对绘制图像多个部分进行优化,可以对局部进行控制
void drawAtlas(Image atlas,List<RSTransform> transforms,List<Rect> rects,List<Color>? colors,BlendMode? blendMode,Rect? cullRect,Paint paint);
void drawRawAtlas(Image atlas,Float32List rstTransforms,Float32List rects,Int32List? colors,BlendMode? blendMode,Rect? cullRect,Paint paint);
/// 绘制阴影
void drawShadow(Path path, Color color, double elevation, bool transparentOccluder);

四、绘制的路径

Canvas使用Path来描述描述2D图形路径,路径可以是线段、二次贝塞尔曲线、三次贝塞尔曲线等,这些都可以组合在一起形成一个复杂的图形;
Path可以通过以下的方法来调用原生层的操作;

factory Path() = _NativePath;factory Path.from(Path source) {final _NativePath clonedPath = _NativePath._();(source as _NativePath)._clone(clonedPath);return clonedPath;}

通过以下方法决定如何计算路径内部;

PathFillType get fillType;
set fillType(PathFillType value);

以下从点开始的路径;

/// 点的移动从开始到重新开始
void moveTo(double x, double y);
void relativeMoveTo(double dx, double dy);/// 直线的连线到重新连线
void lineTo(double x, double y);
void relativeLineTo(double dx, double dy);/// 贝塞尔曲线
void quadraticBezierTo(double x1, double y1, double x2, double y2);
void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2);/// 三次贝塞尔
void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3);
void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3);/// 贝塞尔线段
void conicTo(double x1, double y1, double x2, double y2, double w);
void relativeConicTo(double x1, double y1, double x2, double y2, double w);/// 直线或圆弧
void arcTo(Rect rect, double startAngle, double sweepAngle, bool forceMoveTo);
void arcToPoint(Offset arcEnd, {Radius radius = Radius.zero,double rotation = 0.0,bool largeArc = false,bool clockwise = true,});
void relativeArcToPoint(Offset arcEndDelta, {Radius radius = Radius.zero,double rotation = 0.0,bool largeArc = false,bool clockwise = true,});

以下直接给定图形的路径;

/// 矩形
void addRect(Rect rect);
/// 椭圆
void addOval(Rect oval);
/// 圆弧
void addArc(Rect oval, double startAngle, double sweepAngle);
/// 线段
void addPolygon(List<Offset> points, bool close);
/// 圆角
void addRRect(RRect rrect);

以下是路径的组合运算;

/// 添加路径
void addPath(Path path, Offset offset, {Float64List? matrix4});
/// 添加子路径
void extendWithPath(Path path, Offset offset, {Float64List? matrix4});
/// 关闭路径
void close();
/// 复位
void reset();
/// 点是否在路径内
bool contains(Offset point);
/// 路径的副本
Path shift(Offset offset);
Path transform(Float64List matrix4);
/// 路径的边界
Rect getBounds();/// 对路径进行组合
static Path combine(PathOperation operation, Path path1, Path path2) {final _NativePath path = _NativePath();if (path._op(path1 as _NativePath, path2 as _NativePath, operation.index)) {return path;}throw StateError('Path.combine() failed.  This may be due an invalid path; in particular, check for NaN values.');}
/// 多部分的路径轮廓属性,一个Path通常有0到多个轮廓线组成
PathMetrics computeMetrics({bool forceClosed = false});

五、绘制的画笔

Canvas使用Paint描述如何绘制图形,例如颜色、样式、混合模式等,以上我称之为画笔;
isAntiAlias:抗锯齿;
color:填充的颜色;
blendMode:图形混合时合成的模式;
style:是否绘制形状的内部,形状的边缘,或两者;
strokeWidth:线的宽度;
strokeCap:在绘制的线的末端放置的结束类型;
strokeJoin:连接点的类型;
strokeMiterLimit:斜接长度限制;
maskFilter:蒙版滤镜;
filterQuality:控制采样位图时使用的性能和质量权衡;
shader:形状着色器;
colorFilter:颜色滤镜;
imageFilter:图像滤镜;
invertColors:颜色反转。

以上时Flutter中Canvas绘图部分,具体的应用在实际开发中可能是地图线路绘制、AI图像转换、动画绘制等,如需深入还需了解计算机的渲染机制。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(M)unity受伤反弹以及死亡动画

受伤反弹 1.在人物控制脚本中添加受伤后速度将为0&#xff0c;并添加一个反弹的力 在刷新移动时&#xff0c;需要在没有受伤的状态 public bool isHurt; public float hurtForce; private void FixedUpdate() {if(!isHurt)Move(); }public void GetHurt(Transform attacker) …

策略者模式-C#实现

该实例基于WPF实现&#xff0c;直接上代码&#xff0c;下面为三层架构的代码。 目录 一 Model 二 View 三 ViewModel 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练…

探索元宇宙的未来:数字人对话系统 - Linly-Talker —— “数字人交互,与虚拟的自己互动”

探索元宇宙的未来&#xff1a;数字人对话系统 - Linly-Talker —— “数字人交互&#xff0c;与虚拟的自己互动” 之前空闲的时候我似乎已经写过了有关于数字人的两篇文章&#xff0c;今天更多的写这篇文章就是想探索一下元宇宙的未来&#xff0c;这种数字人对话系统能做什么&…

Unity - gamma space下还原linear space效果

文章目录 环境目的环境问题实践结果处理要点处理细节【OnPostProcessTexture 实现 sRGB 2 Linear 编码】 - 预处理【封装个简单的 *.cginc】 - shader runtime【shader需要gamma space下还原记得 #define _RECOVERY_LINEAR_IN_GAMMA】【颜色参数应用前 和 颜色贴图采样后】【灯…

【UE5】如何给人物骨骼绑定Control Rig用来制作动画(控制)

本篇文章暂时只教绑定人物手部的Control Rig&#xff0c;脚的Control Rig举一反三即可 1&#xff0c;右键-创建-控制绑定 2在控制绑定中-右键创建基本IK 3&#xff0c;填入上臂-下臂-手 4【手和下臂】右键-新建-Add Controls For Selected&#xff0c;&#xff08;或者新建-…

第十四章 RabbitMQ应用

文章目录 前言1、RabbitMQ概念1.1、生产者和消费者1.2、队列1.3、交换机、路由键、绑定1.3.1、交换机类型 2、RabbitMQ运转流程2.1、生产者发送消息流程2.2、消费者接收消息的过程2.3、AMQP协议 3、RabbitMQ windows安装3.1、下载3.2、安装 4、Spring Boot 整合RabbitMQ4.1、在…

【语录】岁月

中年 写中年&#xff0c;应该是年少励志三千里 踌躇百步无寸功&#xff0c;转眼高堂已白发 儿女蹒跚学堂中&#xff0c;不如意事常八九&#xff0c;可与人言无二三 可是诸位&#xff0c;不用悲伤&#xff0c;稻盛和夫说&#xff0c; 人生并不是一场物质的盛宴&#xff0c;而是…

单片机学习笔记---LCD1602调试工具

LCD1602调试工具 这一节开始之前先说明一下&#xff0c;模块化编程相关的知识&#xff08;就是将代码分成多个文件来写&#xff0c;比如函数的定义放在.c文件中&#xff0c;函数的声明写在.h文件中&#xff09;属于是C语言的内容&#xff0c;学过C语言的伙伴应该都知道。由于这…

Vue2.0+Element实现日历组件

(壹)博主介绍 &#x1f320;个人博客&#xff1a; 尔滨三皮⌛程序寄语&#xff1a;木秀于林&#xff0c;风必摧之&#xff1b;行高于人&#xff0c;众必非之。 (贰)文章内容 1、安装依赖 npm install moment2.29.4 --savenpm install lunar0.0.3 --savenpm install lunar-java…

配置华为交换机生成树VBST案例

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系 厦门微思网络​​​​​​https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom 思科认证CCNA\CCNP\CCIE 红帽认证Linux\RHCE\RHC…

代理IP使用指南:风险与注意事项

在当今的数字化时代&#xff0c;使用在线代理IP已经成为一种常见的网络行为。然而&#xff0c;在使用这些代理IP时&#xff0c;我们需要注意一些风险和问题&#xff0c;以确保我们的网络安全和隐本私文。将探讨使用代理IP时需要注意的几个关键问题。 1、代理IP的安全性 使用代理…

设计模式:工厂方法模式

工厂模式属于创建型模式&#xff0c;也被称为多态工厂模式&#xff0c;它在创建对象时提供了一种封装机制&#xff0c;将实际创建对象的代码与使用代码分离&#xff0c;有子类决定要实例化的产品是哪一个&#xff0c;把产品的实例化推迟到子类。 使用场景 重复代码 : 创建对象…

OpenAI ChatGPT-4开发笔记2024-07:Embedding之Text Similarity文本相似度

语义相似性semantic similarity 背景结果 背景 OpenAI has made waves online with its innovative embedding and transcription models, leading to breakthroughs in NLP and speech recognition. These models enhance accuracy, efficiency, and flexibility while speed…

算法每日一题: 边权重均等查询 | 公共子祖先

大家好&#xff0c;我是星恒&#xff0c;今天给大家带来的是一道图里面有关公共子祖先的题目&#xff0c;理解起来简单&#xff0c;大家 题目&#xff1a;leetcode 2846 现有一棵由 n 个节点组成的无向树&#xff0c;节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n …

聊聊大模型 RAG 探索之路的血泪史,一周出Demo,半年用不好

大家好&#xff0c;今天我们来继续看看 RAG 落地的一些有趣的事儿&#xff0c;从技术社群早上的讨论开始&#xff0c;喜欢技术交流的可以文末加入我们 一、从一周出Demo、半年用不好说起 最近读了读2024-傅盛开年AI大课&#xff0c;其中有讲到RAG环节&#xff0c;三张片子比较…

2023.1.23 关于 Redis 哨兵模式详解

目录 引言 人工恢复主节点故障 ​编辑 主从 哨兵模式 Docker 模拟部署哨兵模式 关于端口映射 展现哨兵机制 哨兵重新选取主节点的流程 哨兵模式注意事项 引言 人工恢复主节点故障 1、正常情况 2、主节点宕机 3、程序员主动恢复 先看看该主节点还能不能抢救如果不好定…

统一异常处理

统一异常处理 统一异常处理创建一个类定义方法ControllerAdvice和ExceptionHandler注意事项 统一异常处理 创建一个类 首先,我们来创建一个类,名字随意,这里我们取名ERHandler 定义方法 在ERHandler中,我们可以定义几个类,参数用来接收各种异常,这里的异常可以是任意的,返回…

面试官:你可以说一说你对Jmeter元素的理解吗?下

面试官&#xff1a;你可以说一说你对Jmeter元素的理解吗&#xff1f;下 监听器配置元素CSV数据集配置HTTPCookie管理器HTTP请求默认值登录配置元素 监听器 Listeners&#xff1a;显示测试执行的结果。它们可以以不同的格式显示结果&#xff0c;例如树、表、图形或日志文件 图…

LLM大语言模型(五):用streamlit开发LLM应用

目录 背景准备工作切记streamlit开发LLM demo开一个新页面初始化session先渲染历史消息接收用户输入模拟调用LLM 参考 背景 Streamlit是一个开源Python库&#xff0c;可以轻松创建和共享用于机器学习和数据科学的漂亮的自定义web应用程序&#xff0c;用户可以在几分钟内构建一…

DNS欺骗

DNS(域名系统)作为当前全球最大 、最复杂的分布式层次数据库系统&#xff0c;具有着开放、庞大、复杂的特性。它为全球用户提供域名解析服务&#xff0c;是互联网的重要基础设施。但由于其在设计之初未考虑安全性、人为破坏等因素 &#xff0c;DNS系统在互联网高度发达的今天面…