sketch-json-parse
Version:
sketch-json解析
115 lines (114 loc) • 4.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../common/utils");
const calculateMaskIntersection = (parentMask, childMask) => {
const maskFrame = Object.assign({}, childMask);
const defaultFrame = { _class: 'rect', x: 0, y: 0, width: 0, height: 0 };
if (maskFrame.x + maskFrame.width <= parentMask.x) {
return defaultFrame;
}
if (maskFrame.y + maskFrame.height <= parentMask.y) {
return defaultFrame;
}
if (maskFrame.x >= parentMask.x + parentMask.width) {
return defaultFrame;
}
if (maskFrame.y >= parentMask.y + parentMask.height) {
return defaultFrame;
}
if (maskFrame.x < parentMask.x) {
maskFrame.width = maskFrame.x + maskFrame.width - parentMask.x;
maskFrame.x = parentMask.x;
}
if (maskFrame.y < parentMask.y) {
maskFrame.height = maskFrame.y + maskFrame.height - parentMask.y;
maskFrame.y = parentMask.y;
}
if (maskFrame.x + maskFrame.width > parentMask.x + parentMask.width) {
maskFrame.width = parentMask.x + parentMask.width - maskFrame.x;
}
if (maskFrame.y + maskFrame.height > parentMask.y + parentMask.height) {
maskFrame.height = parentMask.y + parentMask.height - maskFrame.y;
}
return maskFrame;
};
/**
* Mask剪切处理
*
* 作用范围:Mask上层的兄弟元素及其子元素
* 关键点:
* 1. Artboard是最大的Mask
* 2. hasClippingMask Mask图层标识 - 图层被设计为蒙版时对应这个属性,蒙版会剪切在它之下的所有图层
* 3. shouldBreakMaskChain 中断Mask标识
* @param layers
* @param param1
*/
const _mask = (layers, { flag = false, frame, baseFrame }, effectRuleNames, isFilterLayer) => {
let currFrame;
let maskFlag = false;
const defaultFrame = Object.assign({}, frame);
// 标记阶段
for (let i = 0; i < layers.length; i++) {
// 中断mark, 从本层开始
if (layers[i].shouldBreakMaskChain) {
maskFlag = false;
// 同时恢复剪刀主体
frame = Object.assign({}, defaultFrame);
}
// flag 用于深度剪切,剪切容器下的所有元素
if (flag || maskFlag) {
if (flag && maskFlag) {
frame = calculateMaskIntersection(defaultFrame, currFrame);
}
else if (maskFlag) {
frame = Object.assign({}, currFrame);
}
// flag = true;
// 1.切片只被画板剪切
if (layers[i]._class === 'slice') {
layers[i].frame = calculateMaskIntersection(baseFrame, layers[i].frame);
}
else {
// 2.其他图层存在mask的时候用mask进行剪切
layers[i].frame = calculateMaskIntersection(frame, layers[i].frame);
}
}
// 是否中断 删除蒙版外的所有元素,这里先取消,默认蒙版就是要滚动
if (layers[i].hasClippingMask) {
maskFlag = true;
flag = true;
currFrame = Object.assign({}, layers[i].frame);
frame = calculateMaskIntersection(defaultFrame, layers[i].frame);
}
// 递归子元素
if (Array.isArray(layers[i].layers)) {
const scrollList = layers[i].layers.filter((item) => (0, utils_1.tagsEveryIncludes)(item.name, effectRuleNames.scroll) && item._class !== 'group' && !item.hasClippingMask);
if (scrollList.length > 0) {
if (isFilterLayer(layers[i]) && layers[i]._class === 'group') {
const realParent = layers[i].layers.find((item) => item.frame.width === layers[i].frame.width && item.frame.height === layers[i].frame.height);
if (realParent) {
realParent.name = realParent.name + effectRuleNames.scroll;
}
else {
layers[i].name = layers[i].name + effectRuleNames.scroll;
}
}
scrollList.forEach((item) => {
item.frame = { _class: 'rect', x: 0, y: 0, width: 0, height: 0 };
});
}
layers[i].layers = _mask(layers[i].layers, { flag, frame, baseFrame }, effectRuleNames, isFilterLayer);
}
}
// 删除超出画板的图层
layers = layers.filter((layer) => {
if (layer.frame.width === 0 || layer.frame.height === 0) {
return false;
}
return true;
});
return layers;
};
exports.default = (layers, effectRuleNames, isFilterLayer) => {
return _mask(layers, { flag: false, frame: layers[0].frame, baseFrame: layers[0].frame }, effectRuleNames, isFilterLayer);
};