HarmonyOS7 Canvas 文字怎么画得清楚:CanvasTextStyling 实战说明

📅 2026/8/8 11:17:22
HarmonyOS7 Canvas 文字怎么画得清楚:CanvasTextStyling 实战说明
文章目录前言这个案例重点不在内容在样式组合完整代码先搞清楚文字也是画出来的font 是整套文字样式的入口fillText() 和 strokeText() 的区别fillText()strokeText()textAlign 会直接影响你怎么找坐标为什么案例最后又把 textAlign 改回 leftmeasureText() 为什么值得提前知道这类画布文字最常见的使用场景容易踩的坑写在最后前言很多人学Canvas最先想到的都是图形。但到了真实业务里真正决定画面是不是“能用”的常常不是方块和圆而是字。你图形画得再顺标题摆不齐、标签不清楚、数值看着别扭这个画布照样不专业。这篇就专门讲Canvas里的文字绘制。案例覆盖的内容很基础但也正因为基础特别适合拿来建立文字样式的控制感。这个案例重点不在内容在样式组合页面上依次展示了几种文字效果普通填充文字描边文字粗体文字居中文字小字号辅助文字你可以把这一页理解成一个最小文字样式实验台。重点不是这些文案写了什么而是同一块画布里字体、大小、颜色、对齐方式怎么配合使用。完整代码import{DEMO_BG_COLOR,DEMO_CARD_COLOR,DEMO_THEME_COLOR,DEMO_SUBTEXT_COLOR}from./typesEntryComponentstruct CanvasTextStyling{StateisShow:booleantrueprivatesettings:RenderingContextSettingsnewRenderingContextSettings(true)privatecontext:CanvasRenderingContext2DnewCanvasRenderingContext2D(this.settings)build(){Column(){if(this.isShow){Scroll(){Column({space:16}){Text(Canvas 文字绘制).fontSize(16).fontColor(DEMO_THEME_COLOR).fontWeight(FontWeight.Bold)Column(){Text(文字绘制效果).fontSize(13).fontColor(#4D96FF).margin({bottom:8})Column(){Canvas(this.context).onReady((){lety30this.context.font18px sans-serifthis.context.fillStyle#4D96FFthis.context.fillText(fillText 填充文字,10,y)y35this.context.font20px sans-serifthis.context.strokeStyle#FF6B6Bthis.context.lineWidth1this.context.strokeText(strokeText 描边文字,10,y)y35this.context.fontbold 22px sans-serifthis.context.fillStyle#FFA500this.context.fillText(bold 粗体文字,10,y)y40this.context.font14px sans-serifthis.context.fillStyle#6BCB77this.context.textAligncenterthis.context.fillText(textAlign: center 居中,190,y)y30this.context.font12px sans-serifthis.context.fillStyle#999999this.context.textAlignleftthis.context.fillText(font: 12px sans-serif 设置字体,10,y)}).width(100%).height(200).backgroundColor(#F0F0F0).borderRadius(8)}}.backgroundColor(DEMO_CARD_COLOR).padding(12).borderRadius(12)Column({space:6}){Text(文字绘制 API).fontSize(14).fontColor(DEMO_THEME_COLOR).fontWeight(FontWeight.Bold)Text(context.font 16px sans-serif - 设置字体).fontSize(12).fontColor(#333333)Text(context.fillStyle #333 - 设置填充颜色).fontSize(12).fontColor(#333333)Text(context.fillText(text, x, y) - 填充文字).fontSize(12).fontColor(#333333)Text(context.strokeText(text, x, y) - 描边文字).fontSize(12).fontColor(#333333)Text(context.textAlign center/left/right - 对齐).fontSize(12).fontColor(#333333)Text(context.textBaseline top/middle/bottom - 基线).fontSize(12).fontColor(#333333)Text(context.measureText(text).width - 测量文字宽度).fontSize(12).fontColor(#333333)}.width(100%).backgroundColor(#E8F4FD).padding(14).borderRadius(12)}.width(100%)}}Text(CanvasTextStyling - fillText 与 strokeText).fontSize(12).fontColor(DEMO_SUBTEXT_COLOR).margin({top:12})}.width(100%).height(100%).backgroundColor(DEMO_BG_COLOR).padding(16)}}先搞清楚文字也是画出来的在普通 ArkUI 组件里Text()是声明式组件但到了Canvas里文字不是组件而是一种绘制结果。这意味着两件事。第一你得自己决定每一行字的坐标。第二样式不会自动分层字号、粗细、颜色、对齐都要你手动控制。案例里用一个y变量逐行推进lety30this.context.fillText(fillText 填充文字,10,y)y35这是最适合入门的写法因为你能非常明确地看到“下一行为什么会跑到下面去”。font是整套文字样式的入口案例几乎每画一段文字前都会先改fontthis.context.font18px sans-serifthis.context.font20px sans-serifthis.context.fontbold 22px sans-serif这里别只把它当成字号设置。font字符串本质上是一次性描述文字样式的入口里面可以包含粗细、字号、字体族。比如18px sans-serif是普通 18 像素无衬线字体bold 22px sans-serif是粗体 22 像素无衬线字体如果你要在同一块画布里做标题、正文、说明、数值这个属性会频繁切换。fillText()和strokeText()的区别案例把这两个方法并排演示非常适合对比理解。fillText()this.context.fillStyle#4D96FFthis.context.fillText(fillText 填充文字,10,y)这是最常用的文字绘制方式。它画出来的是实心字适合绝大多数正文、标题、数值标签。strokeText()this.context.strokeStyle#FF6B6Bthis.context.lineWidth1this.context.strokeText(strokeText 描边文字,10,y)这画出来的是轮廓字。它不适合大段正文但在海报标题、装饰字、特殊提示上会有用。你可以把它理解成一种更强调视觉风格的文字表现而不是信息密度最高的那种文字。textAlign会直接影响你怎么找坐标案例里有一段居中文字this.context.textAligncenterthis.context.fillText(textAlign: center 居中,190,y)这句代码的重点不只是把字居中而是告诉你当对齐方式变化后传进去的x坐标代表的意义也变了。left时x是文字左边缘center时x是文字中心right时x是文字右边缘如果你后面要做图表标题、柱状图标签、卡片中心文案这个概念必须熟。为什么案例最后又把textAlign改回left这一段其实特别像真实开发this.context.textAlignleftthis.context.fillText(font: 12px sans-serif 设置字体,10,y)因为Canvas上下文是有状态的。你一旦把textAlign改成center后面如果不改回来接下来的文字都会继续按照居中逻辑去画。这也是Canvas初学者最容易被坑的点之一属性不是只影响当前一行而是会保留到你下一次改掉它为止。measureText()为什么值得提前知道案例虽然没有真的调用但把这个 API 列出来了context.measureText(text).width这个方法在真实项目里很实用。比如你要动态计算标签宽度判断某段文字会不会超出画布让图表数值精确居中根据内容长度画背景气泡只靠经验猜宽度后面很容易翻车。能测量就别拍脑袋。这类画布文字最常见的使用场景我最常见的几个场景是图表标题和数值标签海报文案和价格展示进度面板里的状态说明签名板、标注板里的辅助文字这些地方的共同点是文字和图形不是分开的而是要一起组成一个画面。所以你不能只会“显示文字”还得会控制它和图形之间的关系。容易踩的坑第一个坑是忘了不同样式之间要重新设置font。第二个坑是textAlign改了以后没恢复后面的字全部歪掉。第三个坑是只关注字号不关注行距结果文字一多就挤成一团。第四个坑是在Canvas里还拿普通组件排版的思维来想结果越画越乱。写在最后Canvas 里的文字绘制说到底是在训练你对“视觉信息层级”的控制力。标题该大、说明该浅、标签该对齐、数值该稳这些都不是默认送你的而是你一笔一笔配出来的。把这一页吃透后面你再做图表、海报或者复杂状态面板画面会一下子专业很多。