前言
之前讲解过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 < paths.length - 1) {
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 `<path d="${data.join(" ")}" fill="${fill}" />`;
};
小结
psd文件解析官网的相关资料很少,都是靠我们自己不断探索,后期我们将会支持更多的功能。