想在画布上写字?用 TextBlob 绘制自定义文本

在 ArkUI 里,显示文字一般用 Text 组件。但如果你在 Canvas 上画画,想在图形旁边写个标题、给按钮加个标签,怎么办?这时候就需要 TextBlob

TextBlob 是什么?

TextBlob,翻译过来就是"文本块"——由一个或多个相同字体的字符组成的字块。你可以把它理解成"已经排好版的文字":字体、大小、内容都确定了,随时可以画到画布上。

下面是 TextBlob 文本绘制的整体流程:

普通文字

自定义排版

创建 Font 设置字体大小

选择创建方式

makeFromString 从字符串创建

makeFromPosText 指定每个字位置

获得 TextBlob 对象

创建 Brush 设置文字颜色

attachBrush 到 Canvas

canvas.drawTextBlob 绘制文字

detachBrush 释放

创建 TextBlob

方式一:从字符串创建(最常用)

import { drawing } from '@kit.ArkGraphics2D';

let font = new drawing.Font();
font.setSize(48);  // 字体大小 48 像素

let textBlob = drawing.TextBlob.makeFromString('Hello HarmonyOS', font);

makeFromString 接收三个参数:

  • text:要绘制的文字
  • font:Font 对象(控制字体大小、样式等)
  • encoding:编码类型(可选,默认 UTF-8,目前只有 UTF-8 生效)

方式二:指定每个字的位置

如果你想让每个字出现在不同的位置(比如沿着一条曲线排列),用 makeFromPosText

let font = new drawing.Font();
font.setSize(48);

let text = 'Hello';
let points: common2D.Point[] = [
  { x: 0, y: 0 },
  { x: 40, y: 10 },
  { x: 80, y: 0 },
  { x: 120, y: -10 },
  { x: 160, y: 0 }
];

let textBlob = drawing.TextBlob.makeFromPosText(text, points.length, points, font);

每个 Point 对应一个字的位置。上面这段代码让 “Hello” 的每个字母在 y 方向上有轻微的上下波动,做出"手写体"的感觉。

注意:points 数组的长度必须等于字形个数(用 font.countText(text) 获取)。

在 Canvas 上绘制

canvas.drawTextBlob(textBlob, 100, 200);

drawTextBlob 的后两个参数是绘制的起始坐标 (x, y)。

Font:控制字体样式

Font 对象控制文字的大小、样式等属性:

let font = new drawing.Font();
font.setSize(48);  // 字体大小,单位是物理像素

countText 方法可以计算文本的字形数量:

let count = font.countText('Hello');  // 返回 5

完整示例:在画布上画文字

import { RenderNode } from '@kit.ArkUI';
import { common2D, drawing } from '@kit.ArkGraphics2D';

class TextRenderNode extends RenderNode {
  draw(context: DrawContext) {
    const canvas = context.canvas;

    // 画一个红色矩形
    const brush = new drawing.Brush();
    brush.setColor(255, 255, 80, 80);
    canvas.attachBrush(brush);
    canvas.drawRect(50, 50, 300, 150);
    canvas.detachBrush();

    // 在矩形上方写文字
    const textBrush = new drawing.Brush();
    textBrush.setColor(255, 255, 255, 255);  // 白色文字
    canvas.attachBrush(textBrush);

    let font = new drawing.Font();
    font.setSize(36);
    let textBlob = drawing.TextBlob.makeFromString('点击按钮', font);
    canvas.drawTextBlob(textBlob, 100, 120);

    canvas.detachBrush();
  }
}

这段代码画了一个红色矩形,然后在矩形上面写了白色的文字"点击按钮"。

给文字添加特效时,可以按下面的流程操作:

阴影效果

普通文字

需要绘制带特效的文字

创建 TextBlob

需要什么特效?

创建 ShadowLayer

直接设置颜色

设置模糊半径

设置偏移方向

设置阴影颜色

brush.setShadowLayer

brush.setColor

attachBrush + drawTextBlob

给文字加阴影

还记得上一篇提到的 ShadowLayer 吗?它目前只在绘制文字时生效。配合 TextBlob 就能做出文字阴影效果:

import { RenderNode } from '@kit.ArkUI';
import { common2D, drawing } from '@kit.ArkGraphics2D';

class ShadowTextRenderNode extends RenderNode {
  draw(context: DrawContext) {
    const canvas = context.canvas;

    // 创建阴影层:模糊半径5,向右偏移3,向下偏移3,黑色阴影
    let shadowColor: common2D.Color = { alpha: 128, red: 0, green: 0, blue: 0 };
    let shadowLayer = drawing.ShadowLayer.create(5, 3, 3, shadowColor);

    const brush = new drawing.Brush();
    brush.setColor(255, 50, 50, 200);  // 蓝色文字
    brush.setShadowLayer(shadowLayer);
    canvas.attachBrush(brush);

    let font = new drawing.Font();
    font.setSize(60);
    let textBlob = drawing.TextBlob.makeFromString('阴影文字', font);
    canvas.drawTextBlob(textBlob, 50, 150);

    canvas.detachBrush();
  }
}

ShadowLayer.create 的四个参数:

  • blurRadius:阴影模糊半径,越大越"散"
  • x:x 方向偏移,正值向右
  • y:y 方向偏移,正值向下
  • color:阴影颜色

这段代码画出了带阴影的蓝色文字,看起来有立体感。

小结

  • TextBlob:文本块,用 makeFromString 创建,用 drawTextBlob 绘制。
  • Font:控制字体大小,用 countText 计算字形数。
  • makeFromPosText:可以指定每个字的位置,适合做特殊排版。
  • ShadowLayer:给文字加阴影,目前只对文字生效。

下一篇我们来看 PathEffect——怎么画虚线、用自定义形状做虚线效果。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐