剖析 Figma 数据结构:不同图形的特有属性

大家好,我是前端西瓜哥。

上期讲了 Figma 图形的一些常用公共属性:

剖析 Figma 图形对象的基本属性

今天呢,西瓜哥就给大家介绍介绍 Figma 不同图形的特有属性。

使用的 fig 文件解析工具为:

madebyevan.com/figma/fig-f...

矩形

准确来说是圆角矩形,因为支持设置圆角。

ROUNGED_RECTANGLE

圆角相关属性

  • rectangleTopLeftCornerRadius / rectangleTopRightCornerRadius / rectangleBottomLeftCornerRadius / rectangleBottomRightCornerRadius:矩形 4 个圆角半径值。

  • rectangleCornerRadiiIndependent:4 个圆角半径是否各自无关。

  • rectangleCornerToolIndependent:移动图形的某个圆角半径控制点设置圆角半径,其他圆角半径是否同时设置为相同值。rectangleCornerRadiiIndependent 和 rectangleCornerToolIndependent 感觉有点重复,可能需要处理一些特殊场景。

描边相关属性

矩形有 4 条边。

  • borderStrokeWeightsIndependent:边框线是否各自独立设置线宽。

  • borderTopWeight / borderBottomWeight / borderLeftWeight / borderRightWeight:图形的 4 个边框的宽度,当 borderStrokeWeightsIndependent 属性为 true 时会使用。

椭圆

ELLIPSE

  • arcData:圆弧数据。虽然是类型椭圆,但可以通过设置一些属性,表达为圆弧。

  • arcData.startingAngle:圆弧起始弧度。

  • arcData.endingAngle:圆弧结束弧度。

  • arcData.innerRadius:内部空心椭圆半径比椭圆半径的比值,范围 [0, 1],可实现圆环绘制。

两个 angle 的弧度值范围为 [0, PI*2),方向为顺时针,基准方向为正右(对应向量为 (1, 0))。

对应的 UI 层属性为 start、sweep 和 ratio。

上面 UI 层属性值对应的数据层值为:

css 复制代码
{
  startingAngle: 5.497786998748779,
  endingAngle: 3.9269909858703613,
  innerRadius: 0.3861727714538574,
};

ratio 就是 innerRadius,只是转成了百分比的格式。

start 是 startingAngle 弧度转角度后的值

西瓜哥我发现, Figma 在数据层上,弧度值是可以大于 PI,但却并不希望在 UI 层上出现大于 180 度的角度。

所以在计算时,需要将弧度转换到 (-2*PI, 2*PI] 区间,再转为角度。

ini 复制代码
// 弧度区间转换,转为 (-PI * 2, PI * 2]
const normalRad = (rad) => {
  rad %= Math.PI * 2;
  if (rad < 0) {
    rad += Math.PI * 2;
  }

  if (rad > Math.PI) {
    rad -= Math.PI * 2;
  }
  return rad;
};

const getArcDeg = (rad) => {
  rad = normalRad(rad)
  const deg = (rad * 180) / Math.PI;
  return deg
};

getArcDeg(5.497786998748779)
// -45.00000830979934

sweep 为 start 顺时针扫过的弧度(即 endingAngle - startingAngle),比上 PI * 2

ini 复制代码
const getSweep = (start, end) => {
  let sweep = end - start;
  sweep = (sweep);
  return sweep / (Math.PI * 2);
};

getSweep(5.497786998748779, 3.9269909858703613)
// -0.24999995003864073

多边形

等边多边形。

REGULAR_POLYGON

  • count:多边形的边数。

星形

等边星形多边形,一种外观有数个向外凸起的非凸多边形。

START

  • count:星形的角数;

  • starInnerScale:内部比例,内凹半径比外凸半径的比例。

矢量网格

VECTOR

Vector 是 Figma 的一种特殊的矢量网格图形,类似 SVG 的 path,但功能更强大。

它能够表达任意其他类型的图形,所以其他图形经常可以通过一些操作转换为矢量网格类型。

比如双击矩形,给它加一个路径点,然后确认,此时其实它就不再是矩形了,而是矢量网格了。

  • vectorData:矢量数据;

  • vectorData.vectorNetwork:矢量网格数据;

  • vectorData.vectorNetwork.vertices:顶点坐标数组;

  • vectorData.vectorNetwork.segments:片段数组,片段指的是两个顶点的形成的线段,可能还会有控制点(可表示为三阶贝塞尔曲线):

  • vectorData.vectorNetwork.regions:需要填充的区域;

  • vectorData.vectorNetwork.normalizedSize:图形的包围矩形宽高;

  • vectorData.vectorNetwork.styleOverrideTable:样式 id 对应的 handleMirroring 方式(这个 handleMirroring 上期文章讲过);

  • vectorData.cornerSmoothing:圆角平滑度;

简单来说,Figma 数据上表达矢量网格的方式是:

记录每个顶点坐标和对应的编号(使用顶点数组的索引值)。

然后描述所有的 segmens(曲线片段):使用哪两个顶点,以及可能有的两个控制点。

最后还要描述填充区域:记录需要围成区域的顶点 id,以及使用的绕数规则。

这样就描述完一个完整的矢量网格了。

矢量图形比较复杂,之后我会另开一篇文章具体讲解。

线

LINE

矢量网格图形的近亲,也有一个 vectorData 保存一些矢量信息。

对于线条,一般来说会往两边扩展宽度来绘制有宽度的线段(Canvas 2D 和 SVG 都是)。

但 Figma 的 line 稍微有点特别,会保持其中一侧不变,向另一边扩展

这个看似比较奇怪的特性,是有特殊考量的。

Figma 有 "吸附到像素网格" 的功能,这个功能设计师大部分时间都是开启的,作用是让绘制图形的点坐标自动靠近到最近的整数坐标位置

也就是说,大多数场景下,Figma 图形的坐标都是整数

这样在坐标 1 的位置绘制 1px 的线条,会导致 跨越多行像素 的情况,为了看起来不这么粗,就要做抗锯齿,使用半透明的像素去填充多行像素点,但却导致线条会看起来有些点模糊,给用户一种低画质的感觉。

解决方案是偏移到 0.5,这样就只占一行像素,且不需要抗锯齿,就不会有模糊问题了。

于是,Figma 就改为固定一边,然后往另一边扩展线宽,这样绘制 1px 就只会占据一行像素。

箭头

箭头就是矢量网格。没有箭头这么一种类型。

只有一条线,加上一头是一个特殊的箭头样式。

bash 复制代码
{
  type: "VECTOR",
  strokeCap: "ARROW_EQUILATERAL",
  //...
}

和 line 不一样,矢量网格线宽正常地往两边扩展。

图片

图片是特殊的矩形,其填充属性 fillPaints 使用了类型为 IMAGE 的 paint。

文本

TEXT

文本图形,支持富文本。

文本图形的属性非常多,这里只介绍一些常用的。

  • textAlignHorizontal:文本左右对齐方式,默认为 "LEFT";

  • textAlignVertical:文本上下对齐方式,默认为 "TOP";

  • lineHeight:行高;

  • fontName:使用的字体;

  • textData:文本数据,一个属性很多的对象;

  • textData.characters:文本内容字符串;

  • textData.characterStyleIDs:数值数组,记录不同字符使用的样式 id;

  • textData.baselines:基线对象数组,在换行的情况下,基线会有多条;

  • textData.glyphs:每个字形的 SVG 的 path 表达;

  • textData.fontMetaData:字体的元信息,比如字重;

  • ...

  • letterSpacing:字间距;

  • autoRename:自动重命名,默认为 true,此时图形的名称会自定跟随文本内容更新;

  • textAutoResize:文字是有一个包围矩形的,这个属性表示矩形是否根据文字内容自动改变宽高。默认为 WIDTH_AND_HEIGHT(宽高自动根据文字内容和换行适应),此外还有 HEIGHT(宽度固定,高度自适应)、NONE(文字内容不会改变矩形宽高,必要时会溢出矩形)

结尾

这些就是 Figma 各种图形常见的特有属性了,更多属性可以自己试着导出 fig 解析对比参照参照。

下期会看看 Figma 的容器对象的数据结构。

我是前端西瓜哥,欢迎关注我,学习更多图形编辑器知识。


相关阅读,

剖析 Figma 图形对象的基本属性

学到了!Figma 原来是这样表示矩形的

什么?Figma 的 fig 文件格式居然解析出来了

Figma 是如何做协同编辑的?

图形编辑器开发:是否要像 Figma 一样上 wasm

相关推荐
qq_3643717233 分钟前
Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现
前端·vue.js·缓存
y先森1 小时前
CSS3中的弹性布局之侧轴的对齐方式
前端·css·css3
y先森6 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy6 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189117 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿8 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡9 小时前
commitlint校验git提交信息
前端
虾球xz9 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇9 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒9 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript