HarmonyOS APP实战-画图APP - 第7篇:文本绘制功能

发布时间:2026/8/3 22:45:57

HarmonyOS APP实战-画图APP - 第7篇:文本绘制功能
HarmonyOS APP实战-画图APP - 第7篇在画布上添加文字1. 开篇在第6篇中我们完成了绘制模式的切换与交互反馈优化。通过DrawMode枚举Rect、Circle、FreeDraw管理当前绘制模式在工具栏中实现了高亮选中状态并在画布触摸事件中根据模式调用不同的绘制逻辑drawRect、drawCircle、drawPath。顶部显示当前模式标签用户操作时获得明确的视觉反馈。本篇我们将为画图APP增加文字绘制功能。文字是图形创作中不可或缺的元素——添加标题、批注、签名等场景都需要它在画布上呈现。实现思路是用户通过一个弹出窗口输入文字、选择字体大小和颜色然后在画布上点击或拖拽放置文本。我们将使用ohos.graphics.drawing模块的drawTextAPI在Canvas上渲染文字并实现可拖拽定位的交互。2. 核心实现2.1 基础配置首先导入绘制文字所需的模块并扩展我们的状态管理。在Index.ets顶部添加导入。// Index.ets — 基础配置与模块导入import{CanvasRenderingContext2D}fromohos.graphics.drawing;// 定义文字对象的数据结构interfaceTextItem{content:string;// 文字内容fontSize:number;// 字体大小pxcolor:string;// 颜色十六进制字符串x:number;// 文本左上角x坐标y:number;// 文本左上角y坐标width?:number;// 文本渲染宽度用于碰撞检测height?:number;// 文本渲染高度用于碰撞检测}// 扩展DrawMode枚举添加TEXT模式enumDrawMode{Rect,Circle,FreeDraw,Text// 新增文字模式}关键点说明TextItem接口存储文字的所有属性width和height用于触摸命中检测判断用户是否点到文本区域。DrawMode.Text作为新的绘制模式与之前的形状/画笔模式平级。后续我们需要在画布渲染循环中遍历TextItem数组并调用drawText。2.2 FontPicker组件字体大小与颜色选择器用户输入文字时需要同时选择字体大小和颜色。我们创建一个独立的FontPicker组件它显示一个自定义弹窗或内嵌UI。// components/FontPicker.ets — 字体大小与颜色选择器Componentexportstruct FontPicker{ConsumefontSize:number;// 从父组件继承的字体大小ConsumefontColor:string;// 从父组件继承的字体颜色build(){Column(){// 字体大小滑块Row(){Text(字体大小:).fontSize(16).width(80)Slider({value:this.fontSize,min:12,max:120,step:4,style:SliderStyle.OutSet}).width(200).onChange((value:number){this.fontSizevalue;// 通过Consume双向绑定})}.margin({bottom:12})// 颜色选择器预设色块Row(){Text(字体颜色:).fontSize(16).width(80)// 使用Grid展示常用颜色ForEach([#000000,#FF0000,#00FF00,#0000FF,#FFFF00,#FF00FF,#00FFFF,#FFFFFF],(color:string){Circle({width:30,height:30}).fill(color).stroke(this.fontColorcolor?Color.Black:Color.White).strokeWidth(3).margin(4).onClick((){this.fontColorcolor;})})}}.padding(12).backgroundColor(#F5F5F5).borderRadius(8)}}关键点说明使用Consume装饰器实现父子组件双向数据绑定父组件提供fontSize和fontColor两个状态变量。Slider组件控制字体大小范围12~120px步进4px。颜色选择器用8个预设色块点击直接赋值实际项目可扩展为完整的色盘参考第5篇的颜色选择逻辑。此组件被嵌入到文本输入弹窗中跟随弹窗显示。2.3 文本输入与拖拽放置模块TextTool核心逻辑当用户点击工具栏的“文字”按钮后模式切换为Text。点击画布任意位置弹出输入框让用户输入文字内容并确认。文字对象随即出现在点击位置用户可继续拖拽调整位置。// components/TextTool.ets — 文字输入与拖拽放置模块Componentexportstruct TextTool{privatecanvasCtx:CanvasRenderingContext2D;LinktextItems:TextItem[];// 画布上所有文字对象StatefontSize:number36;// 当前字体大小StatefontColor:string#000000;// 当前字体颜色StateisAddingText:booleanfalse;// 是否正在输入文字StateinputContent:string;// 输入框内容privatetextDialogController:CustomDialogController;build(){Column(){// 文字模式专用按钮Button(添加文字).fontSize(16).onClick((){this.isAddingTexttrue;// 弹出自定义对话框用于输入文字this.showTextInputDialog();})}}// 显示文字输入对话框使用CustomDialogshowTextInputDialog(){this.textDialogControllernewCustomDialogController({builder:TextInputDialog({fontSize:this.fontSize,fontColor:this.fontColor,onConfirm:(content:string){this.inputContentcontent;this.isAddingTexttrue;this.textDialogController.close();},onCancel:(){this.isAddingTextfalse;this.textDialogController.close();}}),autoCancel:true,alignment:DialogAlignment.Center,offset:{dx:0,dy:-80}});this.textDialogController.open();}// 在画布上放置文字的触摸事件处理handleCanvasTouch(event:TouchEvent):void{if(this.isAddingTextthis.inputContent){// 获取触摸点坐标相对于画布consttouchXevent.touches[0].x;consttouchYevent.touches[0].y;// 创建一个新的TextItem并添加到textItems数组constnewText:TextItem{content:this.inputContent,fontSize:this.fontSize,color:this.fontColor,x:touchX,y:touchY};this.textItems[...this.textItems,newText];// 重置状态准备下一次输入this.inputContent;this.isAddingTextfalse;// 重绘画布this.redrawCanvas();}else{// 尝试拖拽已有的文字对象this.dragTextItem(event);}}// 拖拽文字在触摸移动时更新坐标dragTextItem(event:TouchEvent){consttouchXevent.touches[0].x;consttouchYevent.touches[0].y;// 遍历文字列表检查触摸点是否落在某个文字区域内for(letithis.textItems.length-1;i0;i--){constitemthis.textItems[i];// 计算文字区域估算宽度content长度*fontSize*0.6高度fontSize*1.2constestimatedWidthitem.content.length*item.fontSize*0.6;constestimatedHeightitem.fontSize*1.2;// 判断触摸点是否在文字矩形区域内if(touchXitem.xtouchXitem.xestimatedWidthtouchYitem.y-estimatedHeighttouchYitem.y){// 更新坐标if(event.typeTouchType.Move){item.xtouchX-estimatedWidth/2;item.ytouchY;this.textItems[...this.textItems];// 触发UI更新this.redrawCanvas();}break;}}}// 重新绘制画布包含所有文字redrawCanvas(){if(!this.canvasCtx)return;// 清空画布并重新绘制所有图形此处简化实际需结合之前的绘制指令this.canvasCtx.clearRect(0,0,this.canvasCtx.width,this.canvasCtx.height);// ... 重新绘制之前的形状 画笔轨迹省略与第3-6篇代码集成this.drawAllTexts();}// 遍历文字列表绘制所有文字drawAllTexts(){if(!this.canvasCtx)return;this.textItems.forEach((item:TextItem){this.canvasCtx.font${item.fontSize}px sans-serif;this.canvasCtx.fillStyleitem.color;this.canvasCtx.textAlignleft;this.canvasCtx.textBaselinetop;this.canvasCtx.fillText(item.content,item.x,item.y);});}}关键点说明使用CustomDialogController弹出输入对话框TextInputDialog组件需另定义用于输入文字内容。触摸事件处理当处于“添加文字”状态且内容非空时触摸点即文字放置位置否则尝试拖拽已有文字。estimatedWidth和estimatedHeight是粗略估算的文字区域用于触摸命中判断。精确计算可使用CanvasRenderingContext2D.measureText但因异步问题本实现采用估算方式仍可满足基本交互。drawAllTexts方法在每次重绘时调用使用fillText绘制文字。font、fillStyle依据TextItem属性动态设置。2.4 在画布组件中集成文字绘制最后将TextTool集成到主画布组件中在渲染循环中调用文字绘制。// Index.ets — 主画布组件核心代码片段Componentstruct DrawingCanvas{privatecanvasCtx:CanvasRenderingContext2DnewCanvasRenderingContext2D();StatecurrentMode:DrawModeDrawMode.Rect;StatetextItems:TextItem[][];// 文字对象数组privatetextTool:TextToolnewTextTool();build(){Column(){// ... 工具栏省略包含模式切换按钮// 文字模式下显示TextTool组件if(this.currentModeDrawMode.Text){TextTool({canvasCtx:this.canvasCtx,textItems:$textItems}).width(100%).height(60)}// 画布区域Canvas(this.canvasCtx).width(100%).layoutWeight(1).backgroundColor(#FFFFFF).onTouch((event:TouchEvent){if(this.currentModeDrawMode.Text){this.textTool.handleCanvasTouch(event);}else{// 原有形状/画笔模式处理略}})}.width(100%).height(100%)}}关键点说明TextItem数组通过State声明驱动UI更新。触摸事件根据currentMode分发文字模式调用TextTool.handleCanvasTouch其他模式走原有逻辑。TextTool组件接收canvasCtx和textItems引用实现跨组件的协作。3. 运行验证在DevEco Studio中运行项目按照以下步骤验证点击工具栏新增的“文字”按钮模式切换为文字模式按钮高亮。点击画布任意位置弹出文字输入对话框。输入文字内容例如“Hello HarmonyOS”通过滑块调整字体大小为48px选择红色。点击“确定”后输入的文字出现在点击位置。再次在文字区域内触摸并拖动文字跟随手指移动。重复上述步骤添加多个文字可叠加在之前的图形之上。预期表现文字清晰渲染颜色和大小与设置一致拖拽行为流畅触摸命中区域基本准确。4. 小结与预告本篇完成了文本绘制功能在画图APP中的集成。核心产出包括定义了TextItem数据结构支持存储内容、字体、颜色、坐标。实现了FontPicker组件提供字体大小和颜色选择UI。实现了TextTool模块包含文字输入对话框、触摸放置和拖拽逻辑。使用CanvasRenderingContext2D.fillTextAPI渲染文字并与原有绘制逻辑共存。至此画图APP已支持矩形、圆形、自由画笔和文字四种绘制元素用户的创作能力大大增强。下一篇《使用effectKit处理图像》将引入ohos.effectKit模块为画布内容添加亮度调节、模糊化、灰度调节等图像特效。届时用户在绘制完成后可选择应用滤镜实现更丰富的视觉效果。我们将在第8篇中构建特效面板并集成到工具栏中。

相关新闻

Open Source Candies生态系统分析:开源项目如何利用免费服务成长

Open Source Candies生态系统分析:开源项目如何利用免费服务成长

2026/8/1 18:30:12

Open Source Candies生态系统分析:开源项目如何利用免费服务成长 【免费下载链接】opensource-candies Free stuff for open source projects 项目地址: https://gitcode.com/gh_mirrors/op/opensource-candies 在开源项目的成长过程中,资源和工具…

Orchestra工具生态系统全解析:从内置工具到自定义工具开发

Orchestra工具生态系统全解析:从内置工具到自定义工具开发

2026/8/3 2:42:59

Orchestra工具生态系统全解析:从内置工具到自定义工具开发 【免费下载链接】orchestra Cognitive Architectures for Multi-Agent Teams 项目地址: https://gitcode.com/gh_mirrors/orchestr/orchestra Orchestra是一个强大的多智能体协作框架,其…

Osg 开发一:OpenSceneGraph 介绍及开发环境设置

Osg 开发一:OpenSceneGraph 介绍及开发环境设置

2026/8/3 2:47:31

文章目录一 OpenSceneGraph 简介1 什么是 OpenSceneGraph2 OSG 中国3 OSG 组成模块二 OSG 开发1 开发环境2 环境设置3 Hello OSG 工程其他一 OpenSceneGraph 简介 1 什么是 OpenSceneGraph OSG 是一个开源的场景图形管理开发库,主要为图形图像应用程序的开发提供场…

Dayz-Cheat-H4ck-A1mbot高级玩法:Speedhack与Freecam功能实战

Dayz-Cheat-H4ck-A1mbot高级玩法:Speedhack与Freecam功能实战

2026/8/3 22:37:52

Dayz-Cheat-H4ck-A1mbot高级玩法:Speedhack与Freecam功能实战 【免费下载链接】Dayz-Cheat-H4ck-A1mbot A project that offers cheats developed with C for DayZ. It aims to improve the game experience with features such as Aimbot, ESP, Spoof. 项目地址:…

Allegro 17.4表贴封装创建全攻略:从焊盘设计到可靠性验证

Allegro 17.4表贴封装创建全攻略:从焊盘设计到可靠性验证

2026/8/3 22:37:52

1. 项目概述:为什么表贴封装是PCB设计的基石在电子硬件设计领域,PCB封装是连接原理图符号与物理世界的桥梁。一个精准、可靠的封装,直接决定了元器件能否被正确焊接、电路功能能否正常实现,乃至整个产品的长期可靠性。对于使用Cad…

构建代理原生应用:从“模型调用”到“系统思维”的范式跃迁

构建代理原生应用:从“模型调用”到“系统思维”的范式跃迁

2026/8/3 22:37:52

👋 大家好,我是 带娃的IT创业者,专注 AI 大模型应用落地、Python 实战进阶与 AI 开发工具链)。代表专栏:《AI大模型应知应会短平快系列100篇》《解密OpenClaw》《解码意识NCTransformer》《WeClaw Agent实战》> &am…

Redisson版本升级实战:避坑连接泄漏、序列化与锁机制变更

Redisson版本升级实战:避坑连接泄漏、序列化与锁机制变更

2026/8/3 22:37:52

1. 从一次深夜告警说起:Redisson升版后的连锁反应 那天凌晨两点,手机突然开始疯狂震动。监控大屏上,核心业务线的几个关键服务接口的TP99响应时间曲线像坐上了火箭,瞬间从几十毫秒飙到了十几秒,紧接着就是一连串的“连…

芯片IDDQ测试:从静态电流原理到量产缺陷检测实战

芯片IDDQ测试:从静态电流原理到量产缺陷检测实战

2026/8/3 22:37:52

1. 项目概述:从“耗电大户”到“漏电侦探” 在芯片设计,尤其是超大规模集成电路(VLSI)的世界里,有一个指标常常让工程师们又爱又恨,它就是 IDDQ ,或者说 静态电流 。乍一听,这似…

nvim-dev-container核心命令详解:DevcontainerStart到RemoveAll全攻略

nvim-dev-container核心命令详解:DevcontainerStart到RemoveAll全攻略

2026/8/3 22:27:52

nvim-dev-container核心命令详解:DevcontainerStart到RemoveAll全攻略 【免费下载链接】nvim-dev-container Neovim dev container support - Mirror of https://codeberg.org/esensar/nvim-dev-container 项目地址: https://gitcode.com/gh_mirrors/nv/nvim-dev-…

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案

2026/8/3 4:49:52

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经从网易云音乐下载了心爱的歌曲&am…

分布式配置中心选型实战:Nacos与Consul在创业场景下的对比

分布式配置中心选型实战:Nacos与Consul在创业场景下的对比

2026/8/3 19:24:18

分布式配置中心选型实战:Nacos与Consul在创业场景下的对比工程导读:本文深入讨论 分布式配置中心选型实战:Nacos与Consul在创业场景下的对比 在生产工程实践中的核心落地方案。基于 分布式架构与微服务设计 视角,剖析实际痛点、架…

MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案

MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案

2026/8/3 20:38:37

MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案 【免费下载链接】MoneyPrinterPlus AI一键批量生成各类短视频,自动批量混剪短视频,自动把视频发布到抖音,快手,小红书,视频号上,赚钱从来没有这么容易过! 支持本地语音模型chatTTS,fasterwhisper,…

从提示词小白到AI内容架构师(20年技术老兵的6阶能力跃迁图谱,仅剩最后87个免费解读名额)

从提示词小白到AI内容架构师(20年技术老兵的6阶能力跃迁图谱,仅剩最后87个免费解读名额)

2026/8/3 0:06:20

更多请点击: https://codechina.net 第一章:AI写作能力跃迁的认知革命 过去五年,AI写作已从“模板填充”迈入“语义共建”阶段——模型不再仅复述训练数据中的句式,而是基于跨文档推理、意图锚定与风格自适应,动态构建…

AU-48八米拾音的信噪比衰减与降噪门限耦合分析

AU-48八米拾音的信噪比衰减与降噪门限耦合分析

2026/8/3 0:06:20

一、"拾音 8 米"这个指标该怎么读AU-48 的规格里,麦克风拾取范围写的是 10cm-800cm,配合 T1/T2 参数切换可选四档:中距离 0.5-2m、近距离 0.1-0.2m、远距离 0.5-5m、超远距离 0.5-8m。"能拾音 8 米"这句话本身没错&#…

LangChain 从 Demo 到团队落地,真正卡壳的是哪一步?

LangChain 从 Demo 到团队落地,真正卡壳的是哪一步?

2026/8/3 0:06:20

聊《LangChain并不难,难的是知道什么时候不该用》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。 摘要 摘要:很多人学 LangChain 都是从调个 API 开始,跑通一个 Demo 觉得挺简单…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/2 17:06:42

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/3 7:25:44

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/3 2:41:27

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…