共计 2721 个字符,预计需要花费 7 分钟才能阅读完成。
前言
之前讲解过psd 文件上传,今天分享一下如何解析文字特效,字体大小,字体等等,顺便讲解如何解析路径。
Font-size 字体大小
上一节关于 矩阵, 我已经写了 psdjs 关于字体解析的 transform 矩阵,因此,我们可以根据这个矩阵计算出 ps 里面字体的大小。
解析字体大小的流程:
第一步:取出 sizes 里面的最大值,psd 解析 sizes 是一个数组,因为 ps 里面可以针对一个文本框文字设置不同的字体大小,假如你解析可以支持不同字体大小的解析,可以根据 length 和 sizes,或者文本框里面每个文字的字体大小,假如不那么精准,可以获取其中最大的一个就可以了。
第二步:通过上一节里面的矩阵,或者字体的变化大小 Math.round(fsize * item.text.transform.yy)
第三步:纠正,假如解析的字体大于文本框高度,或者小于文本框的一半,那么字体大小应该还是有问题的,可以进一步纠正,可以在字体大于图层的高度的时候,设置字体高度为图层高度。
fontFamily 获取
fontFamily 我们这边要有对应的在线字体 cdn 地址,要将 psd 解析的字体名称和我们在线地址的 cdn 对应起来,还是有点麻烦。可以通过如下方式:
一、可以通过单个解析 psd 文件获取字体,要解析所有字体,获取 ps 里面字体解析的名字做映射关系。
二、可以通过 opentype.js 获取字体,这个库提供了一个在线地址,如下:
https://opentype.js.org/font-inspector.html
上面就是方正宝成字体解析的 ps 里面名称。
字体特效
在图层参数下面的 adjustments 下面的 objectEffects 下面的 data 可以获取到文字特效相关参数
备注,特效里面很多字是简写,例如 Rd 是 red 红色,假如是 redFloat 需要乘以 255
关于图片
图片解析成 base64 或者 uint8Array 转换成 file 上传后台,可以参考https://www.haorooms.com/post/js_file_base64_blob
关于路径
如下代码获取路径
let psdData = psd.tree();
let node = psdData.descendants()[0];
console.log(node, node.get("vectorMask"));
let vectorMask = node.get("vectorMask");
const data = vectorMask.export();
const {paths = [] } = data;
console.log(paths, "paths__");
paths.forEach((path) => {
// 变量路径节点
console.log(path, "path___");
});
打印如下:
具体含义可以参考我准备的一个内部分享
解析路径为 svg 相关代码如下:
// 转化无符号浮点数
const signed = function (n) {
let num = n;
if (num> 0x8f) {num = num - 0xff - 1;}
return num;
};
const getPathPosition = function (pathNode) {const { vert, horiz} = pathNode;
return {x: signed(horiz),
y: signed(vert),
};
};
const parsePath = function (path, { width, height}) {const { preceding, anchor, leaving} = path;
const precedingPos = this.getPathPosition(preceding);
const anchorPos = this.getPathPosition(anchor);
const leavingPos = this.getPathPosition(leaving);
// relX 和 relY 保留了 PSD 中原始数据。return {
preceding: {
relX: precedingPos.x,
relY: precedingPos.y,
x: Math.round(width * precedingPos.x),
y: Math.round(height * precedingPos.y),
},
anchor: {
relX: anchorPos.x,
relY: anchorPos.y,
x: Math.round(width * anchorPos.x),
y: Math.round(height * anchorPos.y),
},
leaving: {
relX: leavingPos.x,
relY: leavingPos.y,
x: Math.round(width * leavingPos.x),
y: Math.round(height * leavingPos.y),
},
};
};
const getFillColor = function (node) {const solidColorData = node.get("solidColor");
const clr = solidColorData["Clr"];
return colorHex([Math.round(clr["Rd"]),
Math.round(clr["Grn"]),
Math.round(clr["Bl"]),
]);
};
const toPath = (paths, fill) => {
let head;
const data = [];
paths.forEach((path, index) => {const { preceding, anchor, leaving} = path;
if (index 0) {
// 中间节点
data.push(`${preceding.x}, ${preceding.y} ${anchor.x}, ${anchor.y} ${leaving.x}, ${leaving.y}`
);
} else {
// 记录第一个节点,用于在关闭路径的时候使用
head = path;
data.push(`M ${anchor.x}, ${anchor.y} C${leaving.x}, ${leaving.y}`);
}
} else {data.push(`${preceding.x}, ${preceding.y} ${anchor.x}, ${anchor.y} ${leaving.x}, ${leaving.y} ${head.preceding.x},
${head.preceding.y} ${head.anchor.x}, ${head.anchor.y} Z`);
}
});
return ` `;
};
小结
psd 文件解析官网的相关资料很少,都是靠我们自己不断探索,后期我们将会支持更多的功能。