Skip to content

课程 16 - 绘制文本高级特性

在上一节课中,我们介绍了文本渲染的原理,其中提到过 CanvasKit 相比 Canvas 提供了文本的一些高级绘制特性。本节课我们就将讨论这些特性:

  • 装饰线
  • 阴影
  • 文本选中
  • 文本跟随路径

使用 Path 渲染文本

使用 Figma 的导出 SVG 功能可以发现,它的文本是使用 Path 渲染的。

我发现 font-mesh-pipeline 这个项目的思路很有趣,它使用 harfbuzz WASM 生成矢量化字体,然后使用 GPU 绘制。

输入框

目前我们只实现了文本的绘制,实际在应用中,文本输入框是必不可少的。下图来自 Figma

textarea in figma

Material Design on the GPU

Material Design on the GPU

装饰线

text-decoration

阴影

Pixi.js 提供了 [DropShadowFilter] 来实现阴影效果。

glsl
// @see https://github.com/soimy/pixi-msdf-text/blob/master/src/msdf.frag#L49
vec3 shadowSample = texture2D(uSampler, vTextureCoord - shadowOffset).rgb;
float shadowDist = median(shadowSample.r, shadowSample.g, shadowSample.b);
float distAlpha = smoothstep(0.5 - shadowSmoothing, 0.5 + shadowSmoothing, shadowDist);
vec4 shadow = vec4(shadowColor, shadowAlpha * distAlpha);
gl_FragColor = mix(shadow, text, text.a);

文本跟随路径

在 Figma 社区中,很多用户都在期待这个特性,例如:Make text follow a path or a circle

在 SVG 中可以通过 textPath 实现,详见:Curved Text Along a Path

html
<path
    id="curve"
    d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97"
/>
<text width="500">
    <textPath xlink:href="#curve"> Dangerous Curves Ahead </textPath>
</text>

Skia 提供了 MakeOnPath 方法,详见 Draw text along a path

ts
const textblob = CanvasKit.TextBlob.MakeOnPath(text, skPath, skFont);
canvas.drawTextBlob(textblob, 0, 0, textPaint);

在 Mapbox 中沿道路河流放置 label 是很常见的场景,详见 Map Label Placement in Mapbox GL

Map Label Placement in Mapbox GL

文本选中

加载 Web 字体

扩展阅读

Released under the MIT License.