课程 16 - 绘制文本高级特性
在上一节课中,我们介绍了文本渲染的原理,其中提到过 CanvasKit 相比 Canvas 提供了文本的一些高级绘制特性。本节课我们就将讨论这些特性:
- 装饰线
- 阴影
- 文本选中
- 文本跟随路径
使用 Path 渲染文本
使用 Figma 的导出 SVG 功能可以发现,它的文本是使用 Path 渲染的。
我发现 font-mesh-pipeline 这个项目的思路很有趣,它使用 harfbuzz WASM 生成矢量化字体,然后使用 GPU 绘制。
输入框
目前我们只实现了文本的绘制,实际在应用中,文本输入框是必不可少的。下图来自 Figma
Material Design on the GPU
装饰线
阴影
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