有趣的排版:探索可变字体和着色器(译文)

介绍

我是 Brian,是 Flutter-verse 的新手,我已经在 Google 的 Flutter 团队担任 UX 工程师大约六个月了。作为一名 UX 工程师,我将我作为平面设计师的背景与编码技能相结合,帮助团队构建 Flutter 本身,并展示 Flutter 可以做什么。

这篇博文分享了我作为一名设计师兼开发人员对 Flutter 的第一次实验之一:一个简单的以排版为主题的拼图应用程序。它结合了我在设计方面的创作背景和围绕几个您可能还没有尝试过的 Flutter API 的技术探索:FontVariationAnimationController

我在创建这个应用程序时获得了很多乐趣,并且通过它我亲眼目睹了 Flutter 对于编写代码的设计师或注重设计的开发人员来说有多么棒。

![[0_x9XqN84kLr7s86vK.png]]

排版

平面设计师喜欢研究“排版”,这只是文本样式的一个奇特词。这包括选择字体、大小、布局、间距等。通过所有这些设置,字母本身就可以成为一种艺术形式!作为一名训练有素的设计师,我知道我为这个探索性项目创建的任何东西都会以某种方式涉及使用 Flutter 深入研究排版。在过去的几年里,可变字体已经成为设计师对文本样式进行前所未有的控制的一种有趣方式。这是一个我一直想探索更多的领域,并且随着 Flutter 对可变字体的支持,这似乎是一个绝佳的机会。

您可能已经熟悉一般的字体,它决定了文本块中每个字符的外观。普通字体通常会为我们提供一些可供选择的设置,例如粗细(粗体、普通或斜体)。现在,可变字体将这种定制提升到了一个新的水平。

例如,对于字体的粗细,我们可以选择 100(极轻)和 1000(极粗)之间的任何数字设置。而且这中强大的定制能力并不仅限于粗细;字体创建者可以允许用户设置各种各样的东西,比如字母的宽度,或下行的深度(小写字母如“p”和“y”下降多远)等等。这些不同的设置中的每一个都称为 轴(axis),就像图形的轴一样。

![[0_pO_MkjR1GrLhb8va.jpg]]

Flutter 提供了一种直接的方法来调整小部件中的这些设置,即 TextStyle 使用 fontVariations 字段。例如,以下代码片段将使用 Roboto Flex 可变字体创建文本样式,大小为 18,粗细 (wght) 和宽度 (wdth) 的轴设置可变:

1
2
3
4
5
6
7
8
TextStyle ( 
  fontFamily : 'RobotoFlex' , 
  fontSize : 18 , 
  fontVariations :[ 
    FontVariation ( 'wght' , 374 ), 
    FontVariation ( 'wdth' , 118 ) 
  ], 
)

有关可变字体的更多信息,请查看 Google 字体站点 上的可变字体资源。

设置变体很容易,但我想从一个变体设置到另一个变体设置以及设置组合之间的动画。幸运的是,Flutter 和 Dart 可以很容易地采用两个现有的底层功能(FontVariationAnimationController),并将它们组合在一起以制作我自己的自定义运动排版效果。

对于我的演示,我制作了一个 WonkyChar 小部件和一个 WonkyAnimPalette 帮助程序类,这为我提供了一种简单的方法来选择要在屏幕上显示的任何字母、控制文本大小以及输入与可变字体轴相关的混合设置。该 WonkyChar 小部件还包含一个标准的 FlutterAnimationController 对象,我用它来设置动画。在此示例中,字母 “M” 将以 200 的大小显示,并在四秒的动画中将其粗细从非常细变为非常粗:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
WonkyChar(
  text: 'M',
  size: 200,
  animationDurationMillis: 4000,
  animationSettings: [
    WonkyAnimPalette.weight(
      from: 100,
      to: 900,
    ),
  ],
),

自定义着色器

可变字体的效果非常好,尤其是动画效果,但我想进一步推动我的视觉创造力,看看我能用字母形状做些什么。顺便说一句,我听说 Flutter 刚刚添加了对自定义片段着色器的支持。着色器是在计算机的图形处理单元 (GPU) 上运行的程序,允许开发人员在保持高帧速率的同时创建各种视觉效果。Flutter 支持使用 GLSL 编写着色器,GLSL 是最著名和记录最完备的着色器语言之一,在书籍、网站、YouTube 视频和大量开放式在线课程 (MOOC) 中提供了许多教程和示例。我绝对不是着色器或图形编程方面的专家,但我之前曾对它们进行过修补,所以这是另一个探索 Flutter 功能的好机会,同时培养我自己的技能。

注意:着色器是一个相当高级的编码主题,有关将它们插入 Flutter 应用程序的详细信息超出了本博文的范围。如果您想尝试自己编写一些着色器,请查看 Flutter 文档中的 编写和使用片段着色器 部分进行了解。这是一种非常有趣的编码方法!

最初,只是为了展示一种可能性,我编写了一个简单的 GLSL 着色器,作为我的一个 WonkyChar 小部件(如上所述)上的过滤器,以创建以下效果:

![[0_-N5jTlkJHFmEeb0e.png]]

项目介绍

这些原始组件排版(typography)、可变字体支持和着色器是一个有趣的开始,但它们需要在一个连贯的项目中真正结合在一起。作为学习更多关于 Flutter 和 Flutter 社区编码的练习,我制作了一个简单的基于图块的益智游戏 Type Jam,其灵感来自 2022 Flutter Puzzle Hack 竞赛。在拼图黑客提示的背景下围绕这些想法进行头脑风暴,我提出了以下概念:作为玩家,您必须通过解决一系列基于图块的拼图来帮助一家陷入困境的字体公司将故障字体文件重新组合在一起。

该应用程序的每个屏幕都有一个拼图,由乱七八糟的字母组成,周围是根据可变字体轴(如粗细或宽度)设置动画的整个字母。拼图块上的故障效果是由每个页面上的不同着色器创建的,导致拼图块看起来呈波浪状或断裂等。而且,与常见拼图游戏中的拼图机制不同,我决定让玩家通过以下方式解决拼图旋转瓷砖而不是滑动它们,以便在完成后可以查看整个字母,没有空槽。现在回想起来,这可能让谜题变得有点太简单了,但也许我可以为 2.0 版提出更多挑战!

![[0_90hPGzJLj7qBZp7t.gif]]

如果您想了解这一切是如何组合在一起的,请查看 flutter/samples 存储库中 “experimental” 文件夹中的 Type Jam 应用程序中的 varfont_shader_puzzle 示例。正如我之前提到的,我对 Flutter 还是很陌生,我对着色器只有基本的工作知识,所以我期待着在未来改进它!现在,请将其视为快速演示,而不是模板。

结论

作为一名以设计为中心的用户体验工程师,将我的设计和技术兴趣结合起来创造有趣的排版,并让其他人也可以玩这些字母,这让我感到非常满足。另外,我亲眼看到了 Flutter 作为一种创造性工具的潜力,它可以超越应用程序设计的典型模式。我在制作这个项目时玩得很开心,希望它能激励其他设计师和编码人员尝试他们奇怪而有趣的想法,并将他们的设计作为真正的应用程序付诸实践!

Referene