Commit f6991f50 authored by 张九刚's avatar 张九刚

U

parent 7dd74446
{ {
"name": "psd-parse-web", "name": "psd-parse-web",
"version": "1.0.2", "version": "1.0.2",
"main": "dist/index.js", "main": "src/index.js",
"module": "dist/index.es.js", "module": "dist/index.es.js",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
......
...@@ -11,28 +11,156 @@ var Color = require('color'); ...@@ -11,28 +11,156 @@ var Color = require('color');
var generateUUID = require('uuid/v4'); var generateUUID = require('uuid/v4');
var fs = require("fs-extra"); var fs = require("fs-extra");
var hash = require('object-hash'); var hash = require('object-hash');
var zlib =require('zlib');
const relativePosPrefixMap = {
l: { field: 'left', },
t: { field: 'top', },
r: { field: 'right', },
b: { field: 'bottom', },
h: { field: 'horizonCenter', },
v: { field: 'verticalCenter', },
wp: { field: 'width', },
hp: { field: 'height', },
lp: { field: 'left', },
tp: { field: 'top', },
rp: { field: 'right', },
bp: { field: 'bottom', },
};
async function execute(psdFile, options={}) { const offsetAll = 176;
const {
imagesPath='imagesPath',
} = options;
async function execute(psdFile, options = {}) {
console.log("psdFile:",psdFile);
const tree = await getTree(psdFile); const tree = await getTree(psdFile);
const { mode = 'none', singleView = true } = options;
let offset = { x: 0, y: 0 };
let cutSize = { x: 0, y: 0 };
if (mode !== 'none') {
cutSize.y = offsetAll;
}
switch (mode) {
case 'top':
offset.y = offsetAll;
break;
case 'center':
offset.y = offsetAll / 2;
break;
}
const isCenter = mode === 'center';
let viewRoot = { let viewRoot = {
name: path.basename(psdFile, '.psd'), name: path.basename(psdFile, '.psd'),
type: 'node', componentName: 'Div',
uuid: generateUUID(), uuid: generateUUID(),
}; };
const assets = []; const assets = [];
const imageHashMap = {}; const imageHashMap = {};
let { width: stageWidthOrigin, height: stageHeightOrigin } = tree;
const stageWidth = stageWidthOrigin - cutSize.x || 0;
const stageHeight = stageHeightOrigin - cutSize.y || 0;
await walkNode(tree, async function (node, parent) { await walkNode(tree, async function (node, parent) {
const { name, x, y, width, height, alpha, visible, origin: { layer, layer: { typeTool, solidColor } } } = node; let { name } = node;
const { x, y, width, height, opacity, display, origin: { layer, layer: { typeTool, solidColor } } } = node;
let properties = { let properties = {
width, height, alpha, visible, style: {
width, height, opacity, display,
},
attrs: {
},
className: ""
}; };
const isSecondLayer = singleView && !parent.origin.parent || !singleView && parent.origin.parent && !parent.origin.parent.parent;
const shouldVerticalCenter = isSecondLayer && isCenter;
const { width: parentWidth, height: parentHeight } = parent;
if (name.includes('|') || shouldVerticalCenter) {
try {
let arr = name.split('|');
name = arr[0];
let paramsStr = arr[1];
let relativePos;
if (paramsStr) {
let params = paramsStr.split(';');
relativePos = params[0];
} else if (shouldVerticalCenter) {
relativePos = 'v';
}
if (relativePos) {
let items = relativePos.split(',');
for (let item of items) {
let result = item.match(/[a-zA-Z]+/);
if (!result) {
continue;
}
let prefix = result[0];
let mapItem = relativePosPrefixMap[prefix];
if (mapItem) {
let { field, } = mapItem;
let value = item.substr(prefix.length);
let hasValue = value.length > 0;
let fieldChar = prefix[0];
if (!hasValue) {
switch (fieldChar) {
case 'l':
value = x - offset.x;
break;
case 't':
value = y - offset.y;
break;
case 'r':
value = stageWidth - (x - offset.x) - width;
break;
case 'b':
value = stageHeight - (y - offset.y) - height;
break;
case 'h':
value = x + width / 2 - stageWidthOrigin / 2;
break;
case 'v':
value = y + height / 2 - stageHeightOrigin / 2;
break;
}
}
let isPercent = prefix.endsWith('p');
if (isPercent) {
if (!hasValue) {
switch (fieldChar) {
case 'l':
case 'r':
value /= stageWidth;
break;
case 't':
case 'b':
value /= stageHeight;
break;
}
value = Math.floor(value * 100);
}
value += '%';
} else {
value = parseFloat(value);
if (isNaN(value)) {
value = 0;
}
}
properties.style[field] = value;
}
}
}
} catch (e) {
console.log(e);
}
}
let viewNode = { let viewNode = {
name, name,
properties, properties,
...@@ -40,33 +168,36 @@ async function execute(psdFile, options={}) { ...@@ -40,33 +168,36 @@ async function execute(psdFile, options={}) {
}; };
let dealLater = true; let dealLater = true;
if (x !== 0) { if (x !== 0) {
properties.x = x; if (!properties.style.left) {
properties.style.left = x - (isSecondLayer ? offset.x : 0);
}
} }
if (y !== 0) { if (y !== 0) {
properties.y = y; if (!properties.style.top) {
properties.style.top = y - (isSecondLayer ? offset.y : 0);
}
}
properties.style.position = "absolute"
properties.style.transformOrigin = "0px 0px 0px";
viewNode.rect = {
x: properties.style.left ? properties.style.left : 0,
y: properties.style.top ? properties.style.top : 0,
width: properties.style.width,
height: properties.style.height
} }
if (typeTool) { if (typeTool) {
let fontInfo = typeTool(); let fontInfo = typeTool();
//const fonts = fontInfo.fonts(); properties.attrs.text = fontInfo.textValue;
//const styles = fontInfo.styles();
//const {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;
properties.text = fontInfo.textValue;
const sizes = fontInfo.sizes(); const sizes = fontInfo.sizes();
const colors = fontInfo.colors(); const colors = fontInfo.colors();
properties.size = sizes ? sizes[0] || 20 : 20; properties.style.fontSize = sizes ? sizes[0] || 20 : 20;
let [r, g, b, a] = colors[0]; let [r, g, b, a] = colors[0];
properties.fillColor = `rgba(${r}, ${g}, ${b}, ${a / 255})`; properties.style.color = `rgba(${r}, ${g}, ${b}, ${a / 255})`;
/*properties.textflow = { viewNode.componentName = 'Label';
fonts, styles, RunLengthArray,
};*/
viewNode.type = 'label';
dealLater = false; dealLater = false;
} else if (solidColor) { } else if (solidColor && layer.vectorMask) {
const { r, g, b } = solidColor();
let color = Color({ r, g, b });
let paths = layer.vectorMask().paths; let paths = layer.vectorMask().paths;
if (paths[2].numPoints === 4) { if (paths[2].numPoints === 4) {
let isRect = true; let isRect = true;
...@@ -77,8 +208,9 @@ async function execute(psdFile, options={}) { ...@@ -77,8 +208,9 @@ async function execute(psdFile, options={}) {
} }
} }
if (isRect) { if (isRect) {
viewNode.type = 'rect'; viewNode.componentName = 'Div';
properties.fillColor = '#' + color.rgbNumber().toString(16); const { r, g, b } = solidColor();
properties.style.backgroundColor = `rgba(${r}, ${g}, ${b}, 1)`;
dealLater = false; dealLater = false;
} }
} }
...@@ -86,21 +218,24 @@ async function execute(psdFile, options={}) { ...@@ -86,21 +218,24 @@ async function execute(psdFile, options={}) {
if (dealLater) { if (dealLater) {
if (node.hasOwnProperty('children')) { if (node.hasOwnProperty('children')) {
viewNode.type = 'div'; viewNode.componentName = 'Div';
} else { } else {
viewNode.type = 'image'; viewNode.componentName = 'Image';
let uuid = generateUUID(); let uuid = generateUUID();
const ext = '.png'; const ext = '.png';
const imageFilePath = path.join(imagesPath, uuid + ext); let dataUrl;
await fs.ensureDir(path.dirname(imageFilePath)); try {
let png = node.origin.toPng(); let img = node.origin.toPng();
let buffer = await savePng(png, imageFilePath).catch(e => { dataUrl = img.src;
}); } catch (e) {
//await node.origin.saveAsPng(imageFilePath);
}
if (buffer) { if (dataUrl) {
let base64Data = dataUrl.replace(/^data:image\/\w+;base64,/, "");
let buffer = new Buffer(base64Data, 'base64');
const fileNameHash = hash(buffer); const fileNameHash = hash(buffer);
if (imageHashMap.hasOwnProperty(fileNameHash)) { if (imageHashMap.hasOwnProperty(fileNameHash)) {
uuid = imageHashMap[fileNameHash]; uuid = imageHashMap[fileNameHash];
...@@ -110,14 +245,12 @@ async function execute(psdFile, options={}) { ...@@ -110,14 +245,12 @@ async function execute(psdFile, options={}) {
name, name,
ext, ext,
uuid, uuid,
base64Data,
hash: fileNameHash, hash: fileNameHash,
}); });
} }
const hashFilePath = path.join(imagesPath, fileNameHash + ext); properties.attrs.source = 'asset://' + uuid;
await fs.rename(imageFilePath, hashFilePath);
properties.source = 'asset://' + uuid;
} }
} }
} }
...@@ -130,29 +263,32 @@ async function execute(psdFile, options={}) { ...@@ -130,29 +263,32 @@ async function execute(psdFile, options={}) {
node.view = viewNode; node.view = viewNode;
}); });
let data = {
return { pluginVersion: "0.0.1",
view: viewRoot, reference: "psd",
fileName: path.basename(psdFile, '.psd'),
assets, assets,
} view: viewRoot,
} };
function savePng(png, output) { let dataString = JSON.stringify(data);
return new Promise((resolve, reject) => {
let buffer, buffers = []; let buf = new Buffer(dataString);
png.pack() return await new Promise((resolve, reject) => {
.on('error', reject) zlib.gzip(buf, function (err, res) {
.on('data', (data) => buffers.push(data)) if (err) {
.on('end', () => { reject(err);
buffer = Buffer.concat(buffers) } else {
}) console.log(res.length);
.pipe(fs.createWriteStream(output)) resolve(res);
.on('finish', () => { }
resolve(buffer);
});
}); });
})
} }
module.exports={
module.exports = {
execute execute
} }
\ No newline at end of file
var {execute}= require( '../src/index'); var {execute}= require( '../src/index');
let test = async()=>{ let test = async()=>{
let result = await execute('/Users/davezh/Downloads/1.psd') let result = await execute('/Users/davezh/Downloads/1.psd',{mode:'none',singleView:true})
console.log("---------"); console.log("---------");
console.log(JSON.stringify(result)); console.log(result);
} }
test(); test();
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment