大家好,我是前端西瓜哥。
上期讲了 Figma 图形的一些常用公共属性:
今天呢,西瓜哥就给大家介绍介绍 Figma 不同图形的特有属性。
使用的 fig 文件解析工具为:
矩形
准确来说是圆角矩形,因为支持设置圆角。
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 的容器对象的数据结构。
我是前端西瓜哥,欢迎关注我,学习更多图形编辑器知识。
相关阅读,