Commit b6724e14 authored by rockyl's avatar rockyl

init

parents
Pipeline #163372 failed with stages
in 0 seconds
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
import xml from 'xml';
import path from 'path';
import fs from 'fs-extra';
import Color from 'color';
import generateUUID from 'uuid/v4';
/**
* Created by rockyl on 2019-08-09.
*/
const PSD = require('psd');
async function getTree(psdFilePath) {
const psd = await PSD.open(psdFilePath);
const root = {};
walk(psd.tree(), root);
return root;
}
function walk(psNode, dataNode) {
const {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};
const {left, top, width, height, name, layer: {opacity, visible}} = psNode;
const x = left - pLeft;
const y = top - pTop;
Object.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});
if (psNode.children() && psNode.children().length > 0){
dataNode.children = [];
}
let children = psNode.children();
for (let i = children.length - 1; i >= 0; i--) {
const childPsNode = children[i];
const childDataNode = {};
dataNode.children.push(childDataNode);
walk(childPsNode, childDataNode);
}
}
/**
* Created by rockyl on 2019-08-10.
*/
async function walkNode(node, callback, includeSelf = false) {
if (includeSelf) {
await callback(node, null);
}
if (node.children && node.children.length > 0) {
for (let childNode of node.children) {
await callback(childNode, node);
const result = await walkNode(childNode, callback);
if (result === true) {
break;
}
}
}
}
async function walkObject(obj, callback) {
if(typeof obj === "object"){
for (let key of Object.keys(obj)) {
const value = obj[key];
await callback(key, value, obj);
const result = await walkObject(value, callback);
if (result === true) {
break;
}
}
}
}
/**
* Created by rockyl on 2019-08-10.
*
* 导出exml
*/
const elementTpls = {
'e:Group': [],
'e:Image': {_attr: {source: '{res}'}},
'e:Button': [
{_attr: {label: '{1}',}},
{
'e:skinName': [
{
'e:Skin': [
{_attr: {states: 'up,down,disabled'}},
{
'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},
},
{
'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},
}
]
}
]
}
]
};
async function execute(psdFile, options) {
const {skinFilePath, skinClassName, resPath, resGroupName} = options;
const tree = await getTree(psdFile);
const exmlRoot = [
{
_attr: {
class: skinClassName,
width: tree.width,
height: tree.height,
'xmlns:e': "http://ns.egret.com/eui",
'xmlns:w': "http://ns.egret.com/wing",
},
},
];
const exmlData = {
'e:Skin': exmlRoot
};
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible} = node;
let attributes = {width, height, alpha, visible};
if (x !== 0) {
attributes.x = x;
}
if (y !== 0) {
attributes.y = y;
}
let element;
let tagName;
let imageResName;
let params;
let hasChild = node.hasOwnProperty('children');
if (hasChild) {
tagName = 'e:Group';
} else {
const nameParams = node.name.split('|');
const nodeName = nameParams[0];
attributes.name = nodeName;
imageResName = resGroupName + '_' + nodeName;
const imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
if (nameParams.length === 1) {
tagName = 'e:Image';
} else {
params = nameParams[1].split(',');
tagName = 'e:' + params[0];
}
//element[tagName] = {_attr: attributes};
}
let elementTpl = elementTpls[tagName];
let elementContent;
if (elementTpl) {
elementContent = JSON.parse(JSON.stringify(elementTpl));
} else {
elementContent = {};
}
element = {
[tagName]: elementContent,
};
let attr;
if (Array.isArray(elementContent)) {
attr = elementContent.find(item => item._attr);
if (!attr) {
attr = {_attr: {}};
elementContent.unshift(attr);
}
} else {
attr = elementContent;
}
Object.assign(attr._attr, attributes);
if (imageResName) {
await walkObject(element, function (key, value, obj) {
if (value === '{res}') {
obj[key] = imageResName;
} else if (typeof value === 'string') {
const result = value.match(/{(\d+)}/g);
if(result){
for(let item of result){
const pi = parseInt(item.match(/{(\d+)}/)[1]);
value = value.replace(item, params[pi]);
}
obj[key] = value;
}
}
});
}
if (hasChild) {
node.exmlNode = elementContent;
}
const exmlNode = parent.exmlNode || exmlRoot;
exmlNode.push(element);
});
let exmlStr = xml(exmlData, {declaration: true, indent: true});
await fs.ensureDir(path.dirname(skinFilePath));
await fs.writeFile(skinFilePath, exmlStr);
}
/**
* Created by rockyl on 2019-09-26.
*
* 导出zeroing的视图
*/
async function execute$1(psdFile, options) {
const {
imagesPath,
} = options;
const tree = await getTree(psdFile);
let viewRoot = {
name: path.basename(psdFile, '.psd'),
type: 'node',
};
const assets = [];
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;
let properties = {
width, height, alpha, visible,
};
let viewNode = {
name: node.name,
properties,
};
if (x !== 0) {
properties.x = x;
}
if (y !== 0) {
properties.y = y;
}
if(typeTool){
let fontInfo= typeTool();
const fonts = fontInfo.fonts();
const styles = fontInfo.styles();
const {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;
properties.text = fontInfo.textValue;
properties.textflow = {
fonts, styles, RunLengthArray,
};
viewNode.type = 'label';
}else if(solidColor){
const {r, g, b} = solidColor();
let color = Color({r, g, b});
viewNode.type = 'rect';
properties.fillColor = '#' + color.rgbNumber().toString(16);
}else{
if(node.hasOwnProperty('children')){
viewNode.type = 'node';
}else{
viewNode.type = 'image';
const uuid = generateUUID();
const fileName = Date.now().valueOf();
const ext = '.png';
properties.source = 'asset|' + uuid;
const imageFilePath = path.join(imagesPath, fileName + ext);
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
assets.push({
name: fileName,
ext,
uuid,
});
}
}
let viewParent = parent.view || viewRoot;
if (!viewParent.hasOwnProperty('children')) {
viewParent.children = [];
}
viewParent.children.push(viewNode);
node.view = viewNode;
});
return {
view: viewRoot,
assets,
}
}
export { getTree, execute as toEgret, execute$1 as toZeroing };
//# sourceMappingURL=index.es.js.map
{"version":3,"file":"index.es.js","sources":["../src/psd-tree.js","../src/utils.js","../src/egret.js","../src/zeroing.js"],"sourcesContent":["/**\n * Created by rockyl on 2019-08-09.\n */\n\nconst PSD = require('psd');\n\nexport async function getTree(psdFilePath) {\n\tconst psd = await PSD.open(psdFilePath);\n\tconst root = {};\n\twalk(psd.tree(), root);\n\n\treturn root;\n}\n\nfunction walk(psNode, dataNode) {\n\tconst {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};\n\tconst {left, top, width, height, name, layer: {opacity, visible}} = psNode;\n\tconst x = left - pLeft;\n\tconst y = top - pTop;\n\n\tObject.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});\n\tif (psNode.children() && psNode.children().length > 0){\n\t\tdataNode.children = [];\n\t}\n\n\tlet children = psNode.children();\n\tfor (let i = children.length - 1; i >= 0; i--) {\n\t\tconst childPsNode = children[i];\n\n\t\tconst childDataNode = {};\n\t\tdataNode.children.push(childDataNode);\n\t\twalk(childPsNode, childDataNode)\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nexport async function walkNode(node, callback, includeSelf = false) {\n\tif (includeSelf) {\n\t\tawait callback(node, null);\n\t}\n\tif (node.children && node.children.length > 0) {\n\t\tfor (let childNode of node.children) {\n\t\t\tawait callback(childNode, node);\n\t\t\tconst result = await walkNode(childNode, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function walkObject(obj, callback) {\n\tif(typeof obj === \"object\"){\n\t\tfor (let key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tawait callback(key, value, obj);\n\t\t\tconst result = await walkObject(value, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n *\n * 导出exml\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode, walkObject} from \"./utils\";\nimport xml from \"xml\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nconst elementTpls = {\n\t'e:Group': [],\n\t'e:Image': {_attr: {source: '{res}'}},\n\t'e:Button': [\n\t\t{_attr: {label: '{1}',}},\n\t\t{\n\t\t\t'e:skinName': [\n\t\t\t\t{\n\t\t\t\t\t'e:Skin': [\n\t\t\t\t\t\t{_attr: {states: 'up,down,disabled'}},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n};\n\nexport async function execute(psdFile, options) {\n\tconst {skinFilePath, skinClassName, resPath, resGroupName} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tconst exmlRoot = [\n\t\t{\n\t\t\t_attr: {\n\t\t\t\tclass: skinClassName,\n\t\t\t\twidth: tree.width,\n\t\t\t\theight: tree.height,\n\t\t\t\t'xmlns:e': \"http://ns.egret.com/eui\",\n\t\t\t\t'xmlns:w': \"http://ns.egret.com/wing\",\n\t\t\t},\n\t\t},\n\t];\n\tconst exmlData = {\n\t\t'e:Skin': exmlRoot\n\t};\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible} = node;\n\t\tlet attributes = {width, height, alpha, visible};\n\t\tif (x !== 0) {\n\t\t\tattributes.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tattributes.y = y;\n\t\t}\n\t\tlet element;\n\t\tlet tagName;\n\t\tlet imageResName;\n\t\tlet params;\n\n\t\tlet hasChild = node.hasOwnProperty('children');\n\t\tif (hasChild) {\n\t\t\ttagName = 'e:Group';\n\t\t} else {\n\t\t\tconst nameParams = node.name.split('|');\n\t\t\tconst nodeName = nameParams[0];\n\n\t\t\tattributes.name = nodeName;\n\t\t\timageResName = resGroupName + '_' + nodeName;\n\t\t\tconst imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');\n\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\tif (nameParams.length === 1) {\n\t\t\t\ttagName = 'e:Image';\n\t\t\t} else {\n\t\t\t\tparams = nameParams[1].split(',');\n\t\t\t\ttagName = 'e:' + params[0];\n\t\t\t}\n\n\t\t\t//element[tagName] = {_attr: attributes};\n\t\t}\n\n\t\tlet elementTpl = elementTpls[tagName];\n\t\tlet elementContent;\n\t\tif (elementTpl) {\n\t\t\telementContent = JSON.parse(JSON.stringify(elementTpl));\n\t\t} else {\n\t\t\telementContent = {}\n\t\t}\n\t\telement = {\n\t\t\t[tagName]: elementContent,\n\t\t};\n\n\t\tlet attr;\n\t\tif (Array.isArray(elementContent)) {\n\t\t\tattr = elementContent.find(item => item._attr);\n\t\t\tif (!attr) {\n\t\t\t\tattr = {_attr: {}};\n\t\t\t\telementContent.unshift(attr);\n\t\t\t}\n\t\t} else {\n\t\t\tattr = elementContent;\n\t\t}\n\n\t\tObject.assign(attr._attr, attributes);\n\n\t\tif (imageResName) {\n\t\t\tawait walkObject(element, function (key, value, obj) {\n\t\t\t\tif (value === '{res}') {\n\t\t\t\t\tobj[key] = imageResName;\n\t\t\t\t} else if (typeof value === 'string') {\n\t\t\t\t\tconst result = value.match(/{(\\d+)}/g);\n\t\t\t\t\tif(result){\n\t\t\t\t\t\tfor(let item of result){\n\t\t\t\t\t\t\tconst pi = parseInt(item.match(/{(\\d+)}/)[1]);\n\t\t\t\t\t\t\tvalue = value.replace(item, params[pi])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobj[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tif (hasChild) {\n\t\t\tnode.exmlNode = elementContent;\n\t\t}\n\n\t\tconst exmlNode = parent.exmlNode || exmlRoot;\n\t\texmlNode.push(element);\n\t});\n\n\tlet exmlStr = xml(exmlData, {declaration: true, indent: true});\n\tawait fs.ensureDir(path.dirname(skinFilePath));\n\tawait fs.writeFile(skinFilePath, exmlStr);\n\n}","/**\n * Created by rockyl on 2019-09-26.\n *\n * 导出zeroing的视图\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode} from \"./utils\";\nimport path from 'path'\nimport Color from 'color'\nimport generateUUID from 'uuid/v4'\nimport fs from \"fs-extra\";\n\nexport async function execute(psdFile, options) {\n\tconst {\n\t\timagesPath,\n\t} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tlet viewRoot = {\n\t\tname: path.basename(psdFile, '.psd'),\n\t\ttype: 'node',\n\t};\n\n\tconst assets = [];\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;\n\t\tlet properties = {\n\t\t\twidth, height, alpha, visible,\n\t\t};\n\t\tlet viewNode = {\n\t\t\tname: node.name,\n\t\t\tproperties,\n\t\t};\n\t\tif (x !== 0) {\n\t\t\tproperties.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tproperties.y = y;\n\t\t}\n\n\t\tif(typeTool){\n\t\t\tlet fontInfo= typeTool();\n\t\t\tconst fonts = fontInfo.fonts();\n\t\t\tconst styles = fontInfo.styles();\n\t\t\tconst {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;\n\n\t\t\tproperties.text = fontInfo.textValue;\n\t\t\tproperties.textflow = {\n\t\t\t\tfonts, styles, RunLengthArray,\n\t\t\t};\n\t\t\tviewNode.type = 'label';\n\t\t}else if(solidColor){\n\t\t\tconst {r, g, b} = solidColor();\n\t\t\tlet color = Color({r, g, b});\n\n\t\t\tviewNode.type = 'rect';\n\t\t\tproperties.fillColor = '#' + color.rgbNumber().toString(16);\n\t\t}else{\n\t\t\tif(node.hasOwnProperty('children')){\n\t\t\t\tviewNode.type = 'node';\n\t\t\t}else{\n\t\t\t\tviewNode.type = 'image';\n\n\t\t\t\tconst uuid = generateUUID();\n\t\t\t\tconst fileName = Date.now().valueOf();\n\t\t\t\tconst ext = '.png';\n\n\t\t\t\tproperties.source = 'asset|' + uuid;\n\n\t\t\t\tconst imageFilePath = path.join(imagesPath, fileName + ext);\n\t\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\t\tassets.push({\n\t\t\t\t\tname: fileName,\n\t\t\t\t\text,\n\t\t\t\t\tuuid,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tlet viewParent = parent.view || viewRoot;\n\t\tif (!viewParent.hasOwnProperty('children')) {\n\t\t\tviewParent.children = [];\n\t\t}\n\t\tviewParent.children.push(viewNode);\n\n\t\tnode.view = viewNode;\n\t});\n\n\treturn {\n\t\tview: viewRoot,\n\t\tassets,\n\t}\n}\n"],"names":["execute"],"mappings":"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"}
\ No newline at end of file
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var xml = _interopDefault(require('xml'));
var path = _interopDefault(require('path'));
var fs = _interopDefault(require('fs-extra'));
var Color = _interopDefault(require('color'));
var generateUUID = _interopDefault(require('uuid/v4'));
/**
* Created by rockyl on 2019-08-09.
*/
const PSD = require('psd');
async function getTree(psdFilePath) {
const psd = await PSD.open(psdFilePath);
const root = {};
walk(psd.tree(), root);
return root;
}
function walk(psNode, dataNode) {
const {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};
const {left, top, width, height, name, layer: {opacity, visible}} = psNode;
const x = left - pLeft;
const y = top - pTop;
Object.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});
if (psNode.children() && psNode.children().length > 0){
dataNode.children = [];
}
let children = psNode.children();
for (let i = children.length - 1; i >= 0; i--) {
const childPsNode = children[i];
const childDataNode = {};
dataNode.children.push(childDataNode);
walk(childPsNode, childDataNode);
}
}
/**
* Created by rockyl on 2019-08-10.
*/
async function walkNode(node, callback, includeSelf = false) {
if (includeSelf) {
await callback(node, null);
}
if (node.children && node.children.length > 0) {
for (let childNode of node.children) {
await callback(childNode, node);
const result = await walkNode(childNode, callback);
if (result === true) {
break;
}
}
}
}
async function walkObject(obj, callback) {
if(typeof obj === "object"){
for (let key of Object.keys(obj)) {
const value = obj[key];
await callback(key, value, obj);
const result = await walkObject(value, callback);
if (result === true) {
break;
}
}
}
}
/**
* Created by rockyl on 2019-08-10.
*
* 导出exml
*/
const elementTpls = {
'e:Group': [],
'e:Image': {_attr: {source: '{res}'}},
'e:Button': [
{_attr: {label: '{1}',}},
{
'e:skinName': [
{
'e:Skin': [
{_attr: {states: 'up,down,disabled'}},
{
'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},
},
{
'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},
}
]
}
]
}
]
};
async function execute(psdFile, options) {
const {skinFilePath, skinClassName, resPath, resGroupName} = options;
const tree = await getTree(psdFile);
const exmlRoot = [
{
_attr: {
class: skinClassName,
width: tree.width,
height: tree.height,
'xmlns:e': "http://ns.egret.com/eui",
'xmlns:w': "http://ns.egret.com/wing",
},
},
];
const exmlData = {
'e:Skin': exmlRoot
};
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible} = node;
let attributes = {width, height, alpha, visible};
if (x !== 0) {
attributes.x = x;
}
if (y !== 0) {
attributes.y = y;
}
let element;
let tagName;
let imageResName;
let params;
let hasChild = node.hasOwnProperty('children');
if (hasChild) {
tagName = 'e:Group';
} else {
const nameParams = node.name.split('|');
const nodeName = nameParams[0];
attributes.name = nodeName;
imageResName = resGroupName + '_' + nodeName;
const imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
if (nameParams.length === 1) {
tagName = 'e:Image';
} else {
params = nameParams[1].split(',');
tagName = 'e:' + params[0];
}
//element[tagName] = {_attr: attributes};
}
let elementTpl = elementTpls[tagName];
let elementContent;
if (elementTpl) {
elementContent = JSON.parse(JSON.stringify(elementTpl));
} else {
elementContent = {};
}
element = {
[tagName]: elementContent,
};
let attr;
if (Array.isArray(elementContent)) {
attr = elementContent.find(item => item._attr);
if (!attr) {
attr = {_attr: {}};
elementContent.unshift(attr);
}
} else {
attr = elementContent;
}
Object.assign(attr._attr, attributes);
if (imageResName) {
await walkObject(element, function (key, value, obj) {
if (value === '{res}') {
obj[key] = imageResName;
} else if (typeof value === 'string') {
const result = value.match(/{(\d+)}/g);
if(result){
for(let item of result){
const pi = parseInt(item.match(/{(\d+)}/)[1]);
value = value.replace(item, params[pi]);
}
obj[key] = value;
}
}
});
}
if (hasChild) {
node.exmlNode = elementContent;
}
const exmlNode = parent.exmlNode || exmlRoot;
exmlNode.push(element);
});
let exmlStr = xml(exmlData, {declaration: true, indent: true});
await fs.ensureDir(path.dirname(skinFilePath));
await fs.writeFile(skinFilePath, exmlStr);
}
/**
* Created by rockyl on 2019-09-26.
*
* 导出zeroing的视图
*/
async function execute$1(psdFile, options) {
const {
imagesPath,
} = options;
const tree = await getTree(psdFile);
let viewRoot = {
name: path.basename(psdFile, '.psd'),
type: 'node',
};
const assets = [];
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;
let properties = {
width, height, alpha, visible,
};
let viewNode = {
name: node.name,
properties,
};
if (x !== 0) {
properties.x = x;
}
if (y !== 0) {
properties.y = y;
}
if(typeTool){
let fontInfo= typeTool();
const fonts = fontInfo.fonts();
const styles = fontInfo.styles();
const {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;
properties.text = fontInfo.textValue;
properties.textflow = {
fonts, styles, RunLengthArray,
};
viewNode.type = 'label';
}else if(solidColor){
const {r, g, b} = solidColor();
let color = Color({r, g, b});
viewNode.type = 'rect';
properties.fillColor = '#' + color.rgbNumber().toString(16);
}else{
if(node.hasOwnProperty('children')){
viewNode.type = 'node';
}else{
viewNode.type = 'image';
const uuid = generateUUID();
const fileName = Date.now().valueOf();
const ext = '.png';
properties.source = 'asset|' + uuid;
const imageFilePath = path.join(imagesPath, fileName + ext);
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
assets.push({
name: fileName,
ext,
uuid,
});
}
}
let viewParent = parent.view || viewRoot;
if (!viewParent.hasOwnProperty('children')) {
viewParent.children = [];
}
viewParent.children.push(viewNode);
node.view = viewNode;
});
return {
view: viewRoot,
assets,
}
}
exports.getTree = getTree;
exports.toEgret = execute;
exports.toZeroing = execute$1;
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sources":["../src/psd-tree.js","../src/utils.js","../src/egret.js","../src/zeroing.js"],"sourcesContent":["/**\n * Created by rockyl on 2019-08-09.\n */\n\nconst PSD = require('psd');\n\nexport async function getTree(psdFilePath) {\n\tconst psd = await PSD.open(psdFilePath);\n\tconst root = {};\n\twalk(psd.tree(), root);\n\n\treturn root;\n}\n\nfunction walk(psNode, dataNode) {\n\tconst {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};\n\tconst {left, top, width, height, name, layer: {opacity, visible}} = psNode;\n\tconst x = left - pLeft;\n\tconst y = top - pTop;\n\n\tObject.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});\n\tif (psNode.children() && psNode.children().length > 0){\n\t\tdataNode.children = [];\n\t}\n\n\tlet children = psNode.children();\n\tfor (let i = children.length - 1; i >= 0; i--) {\n\t\tconst childPsNode = children[i];\n\n\t\tconst childDataNode = {};\n\t\tdataNode.children.push(childDataNode);\n\t\twalk(childPsNode, childDataNode)\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nexport async function walkNode(node, callback, includeSelf = false) {\n\tif (includeSelf) {\n\t\tawait callback(node, null);\n\t}\n\tif (node.children && node.children.length > 0) {\n\t\tfor (let childNode of node.children) {\n\t\t\tawait callback(childNode, node);\n\t\t\tconst result = await walkNode(childNode, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function walkObject(obj, callback) {\n\tif(typeof obj === \"object\"){\n\t\tfor (let key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tawait callback(key, value, obj);\n\t\t\tconst result = await walkObject(value, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n *\n * 导出exml\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode, walkObject} from \"./utils\";\nimport xml from \"xml\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nconst elementTpls = {\n\t'e:Group': [],\n\t'e:Image': {_attr: {source: '{res}'}},\n\t'e:Button': [\n\t\t{_attr: {label: '{1}',}},\n\t\t{\n\t\t\t'e:skinName': [\n\t\t\t\t{\n\t\t\t\t\t'e:Skin': [\n\t\t\t\t\t\t{_attr: {states: 'up,down,disabled'}},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n};\n\nexport async function execute(psdFile, options) {\n\tconst {skinFilePath, skinClassName, resPath, resGroupName} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tconst exmlRoot = [\n\t\t{\n\t\t\t_attr: {\n\t\t\t\tclass: skinClassName,\n\t\t\t\twidth: tree.width,\n\t\t\t\theight: tree.height,\n\t\t\t\t'xmlns:e': \"http://ns.egret.com/eui\",\n\t\t\t\t'xmlns:w': \"http://ns.egret.com/wing\",\n\t\t\t},\n\t\t},\n\t];\n\tconst exmlData = {\n\t\t'e:Skin': exmlRoot\n\t};\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible} = node;\n\t\tlet attributes = {width, height, alpha, visible};\n\t\tif (x !== 0) {\n\t\t\tattributes.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tattributes.y = y;\n\t\t}\n\t\tlet element;\n\t\tlet tagName;\n\t\tlet imageResName;\n\t\tlet params;\n\n\t\tlet hasChild = node.hasOwnProperty('children');\n\t\tif (hasChild) {\n\t\t\ttagName = 'e:Group';\n\t\t} else {\n\t\t\tconst nameParams = node.name.split('|');\n\t\t\tconst nodeName = nameParams[0];\n\n\t\t\tattributes.name = nodeName;\n\t\t\timageResName = resGroupName + '_' + nodeName;\n\t\t\tconst imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');\n\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\tif (nameParams.length === 1) {\n\t\t\t\ttagName = 'e:Image';\n\t\t\t} else {\n\t\t\t\tparams = nameParams[1].split(',');\n\t\t\t\ttagName = 'e:' + params[0];\n\t\t\t}\n\n\t\t\t//element[tagName] = {_attr: attributes};\n\t\t}\n\n\t\tlet elementTpl = elementTpls[tagName];\n\t\tlet elementContent;\n\t\tif (elementTpl) {\n\t\t\telementContent = JSON.parse(JSON.stringify(elementTpl));\n\t\t} else {\n\t\t\telementContent = {}\n\t\t}\n\t\telement = {\n\t\t\t[tagName]: elementContent,\n\t\t};\n\n\t\tlet attr;\n\t\tif (Array.isArray(elementContent)) {\n\t\t\tattr = elementContent.find(item => item._attr);\n\t\t\tif (!attr) {\n\t\t\t\tattr = {_attr: {}};\n\t\t\t\telementContent.unshift(attr);\n\t\t\t}\n\t\t} else {\n\t\t\tattr = elementContent;\n\t\t}\n\n\t\tObject.assign(attr._attr, attributes);\n\n\t\tif (imageResName) {\n\t\t\tawait walkObject(element, function (key, value, obj) {\n\t\t\t\tif (value === '{res}') {\n\t\t\t\t\tobj[key] = imageResName;\n\t\t\t\t} else if (typeof value === 'string') {\n\t\t\t\t\tconst result = value.match(/{(\\d+)}/g);\n\t\t\t\t\tif(result){\n\t\t\t\t\t\tfor(let item of result){\n\t\t\t\t\t\t\tconst pi = parseInt(item.match(/{(\\d+)}/)[1]);\n\t\t\t\t\t\t\tvalue = value.replace(item, params[pi])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobj[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tif (hasChild) {\n\t\t\tnode.exmlNode = elementContent;\n\t\t}\n\n\t\tconst exmlNode = parent.exmlNode || exmlRoot;\n\t\texmlNode.push(element);\n\t});\n\n\tlet exmlStr = xml(exmlData, {declaration: true, indent: true});\n\tawait fs.ensureDir(path.dirname(skinFilePath));\n\tawait fs.writeFile(skinFilePath, exmlStr);\n\n}","/**\n * Created by rockyl on 2019-09-26.\n *\n * 导出zeroing的视图\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode} from \"./utils\";\nimport path from 'path'\nimport Color from 'color'\nimport generateUUID from 'uuid/v4'\nimport fs from \"fs-extra\";\n\nexport async function execute(psdFile, options) {\n\tconst {\n\t\timagesPath,\n\t} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tlet viewRoot = {\n\t\tname: path.basename(psdFile, '.psd'),\n\t\ttype: 'node',\n\t};\n\n\tconst assets = [];\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;\n\t\tlet properties = {\n\t\t\twidth, height, alpha, visible,\n\t\t};\n\t\tlet viewNode = {\n\t\t\tname: node.name,\n\t\t\tproperties,\n\t\t};\n\t\tif (x !== 0) {\n\t\t\tproperties.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tproperties.y = y;\n\t\t}\n\n\t\tif(typeTool){\n\t\t\tlet fontInfo= typeTool();\n\t\t\tconst fonts = fontInfo.fonts();\n\t\t\tconst styles = fontInfo.styles();\n\t\t\tconst {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;\n\n\t\t\tproperties.text = fontInfo.textValue;\n\t\t\tproperties.textflow = {\n\t\t\t\tfonts, styles, RunLengthArray,\n\t\t\t};\n\t\t\tviewNode.type = 'label';\n\t\t}else if(solidColor){\n\t\t\tconst {r, g, b} = solidColor();\n\t\t\tlet color = Color({r, g, b});\n\n\t\t\tviewNode.type = 'rect';\n\t\t\tproperties.fillColor = '#' + color.rgbNumber().toString(16);\n\t\t}else{\n\t\t\tif(node.hasOwnProperty('children')){\n\t\t\t\tviewNode.type = 'node';\n\t\t\t}else{\n\t\t\t\tviewNode.type = 'image';\n\n\t\t\t\tconst uuid = generateUUID();\n\t\t\t\tconst fileName = Date.now().valueOf();\n\t\t\t\tconst ext = '.png';\n\n\t\t\t\tproperties.source = 'asset|' + uuid;\n\n\t\t\t\tconst imageFilePath = path.join(imagesPath, fileName + ext);\n\t\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\t\tassets.push({\n\t\t\t\t\tname: fileName,\n\t\t\t\t\text,\n\t\t\t\t\tuuid,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tlet viewParent = parent.view || viewRoot;\n\t\tif (!viewParent.hasOwnProperty('children')) {\n\t\t\tviewParent.children = [];\n\t\t}\n\t\tviewParent.children.push(viewNode);\n\n\t\tnode.view = viewNode;\n\t});\n\n\treturn {\n\t\tview: viewRoot,\n\t\tassets,\n\t}\n}\n"],"names":["execute"],"mappings":"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"}
\ No newline at end of file
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('xml'), require('path'), require('fs-extra'), require('color'), require('uuid/v4')) :
typeof define === 'function' && define.amd ? define(['exports', 'xml', 'path', 'fs-extra', 'color', 'uuid/v4'], factory) :
(global = global || self, factory(global['psd-parse'] = {}, global.xml, global.path, global.fs, global.Color, global.generateUUID));
}(this, function (exports, xml, path, fs, Color, generateUUID) { 'use strict';
xml = xml && xml.hasOwnProperty('default') ? xml['default'] : xml;
path = path && path.hasOwnProperty('default') ? path['default'] : path;
fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs;
Color = Color && Color.hasOwnProperty('default') ? Color['default'] : Color;
generateUUID = generateUUID && generateUUID.hasOwnProperty('default') ? generateUUID['default'] : generateUUID;
/**
* Created by rockyl on 2019-08-09.
*/
const PSD = require('psd');
async function getTree(psdFilePath) {
const psd = await PSD.open(psdFilePath);
const root = {};
walk(psd.tree(), root);
return root;
}
function walk(psNode, dataNode) {
const {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};
const {left, top, width, height, name, layer: {opacity, visible}} = psNode;
const x = left - pLeft;
const y = top - pTop;
Object.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});
if (psNode.children() && psNode.children().length > 0){
dataNode.children = [];
}
let children = psNode.children();
for (let i = children.length - 1; i >= 0; i--) {
const childPsNode = children[i];
const childDataNode = {};
dataNode.children.push(childDataNode);
walk(childPsNode, childDataNode);
}
}
/**
* Created by rockyl on 2019-08-10.
*/
async function walkNode(node, callback, includeSelf = false) {
if (includeSelf) {
await callback(node, null);
}
if (node.children && node.children.length > 0) {
for (let childNode of node.children) {
await callback(childNode, node);
const result = await walkNode(childNode, callback);
if (result === true) {
break;
}
}
}
}
async function walkObject(obj, callback) {
if(typeof obj === "object"){
for (let key of Object.keys(obj)) {
const value = obj[key];
await callback(key, value, obj);
const result = await walkObject(value, callback);
if (result === true) {
break;
}
}
}
}
/**
* Created by rockyl on 2019-08-10.
*
* 导出exml
*/
const elementTpls = {
'e:Group': [],
'e:Image': {_attr: {source: '{res}'}},
'e:Button': [
{_attr: {label: '{1}',}},
{
'e:skinName': [
{
'e:Skin': [
{_attr: {states: 'up,down,disabled'}},
{
'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},
},
{
'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},
}
]
}
]
}
]
};
async function execute(psdFile, options) {
const {skinFilePath, skinClassName, resPath, resGroupName} = options;
const tree = await getTree(psdFile);
const exmlRoot = [
{
_attr: {
class: skinClassName,
width: tree.width,
height: tree.height,
'xmlns:e': "http://ns.egret.com/eui",
'xmlns:w': "http://ns.egret.com/wing",
},
},
];
const exmlData = {
'e:Skin': exmlRoot
};
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible} = node;
let attributes = {width, height, alpha, visible};
if (x !== 0) {
attributes.x = x;
}
if (y !== 0) {
attributes.y = y;
}
let element;
let tagName;
let imageResName;
let params;
let hasChild = node.hasOwnProperty('children');
if (hasChild) {
tagName = 'e:Group';
} else {
const nameParams = node.name.split('|');
const nodeName = nameParams[0];
attributes.name = nodeName;
imageResName = resGroupName + '_' + nodeName;
const imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
if (nameParams.length === 1) {
tagName = 'e:Image';
} else {
params = nameParams[1].split(',');
tagName = 'e:' + params[0];
}
//element[tagName] = {_attr: attributes};
}
let elementTpl = elementTpls[tagName];
let elementContent;
if (elementTpl) {
elementContent = JSON.parse(JSON.stringify(elementTpl));
} else {
elementContent = {};
}
element = {
[tagName]: elementContent,
};
let attr;
if (Array.isArray(elementContent)) {
attr = elementContent.find(item => item._attr);
if (!attr) {
attr = {_attr: {}};
elementContent.unshift(attr);
}
} else {
attr = elementContent;
}
Object.assign(attr._attr, attributes);
if (imageResName) {
await walkObject(element, function (key, value, obj) {
if (value === '{res}') {
obj[key] = imageResName;
} else if (typeof value === 'string') {
const result = value.match(/{(\d+)}/g);
if(result){
for(let item of result){
const pi = parseInt(item.match(/{(\d+)}/)[1]);
value = value.replace(item, params[pi]);
}
obj[key] = value;
}
}
});
}
if (hasChild) {
node.exmlNode = elementContent;
}
const exmlNode = parent.exmlNode || exmlRoot;
exmlNode.push(element);
});
let exmlStr = xml(exmlData, {declaration: true, indent: true});
await fs.ensureDir(path.dirname(skinFilePath));
await fs.writeFile(skinFilePath, exmlStr);
}
/**
* Created by rockyl on 2019-09-26.
*
* 导出zeroing的视图
*/
async function execute$1(psdFile, options) {
const {
imagesPath,
} = options;
const tree = await getTree(psdFile);
let viewRoot = {
name: path.basename(psdFile, '.psd'),
type: 'node',
};
const assets = [];
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;
let properties = {
width, height, alpha, visible,
};
let viewNode = {
name: node.name,
properties,
};
if (x !== 0) {
properties.x = x;
}
if (y !== 0) {
properties.y = y;
}
if(typeTool){
let fontInfo= typeTool();
const fonts = fontInfo.fonts();
const styles = fontInfo.styles();
const {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;
properties.text = fontInfo.textValue;
properties.textflow = {
fonts, styles, RunLengthArray,
};
viewNode.type = 'label';
}else if(solidColor){
const {r, g, b} = solidColor();
let color = Color({r, g, b});
viewNode.type = 'rect';
properties.fillColor = '#' + color.rgbNumber().toString(16);
}else{
if(node.hasOwnProperty('children')){
viewNode.type = 'node';
}else{
viewNode.type = 'image';
const uuid = generateUUID();
const fileName = Date.now().valueOf();
const ext = '.png';
properties.source = 'asset|' + uuid;
const imageFilePath = path.join(imagesPath, fileName + ext);
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
assets.push({
name: fileName,
ext,
uuid,
});
}
}
let viewParent = parent.view || viewRoot;
if (!viewParent.hasOwnProperty('children')) {
viewParent.children = [];
}
viewParent.children.push(viewNode);
node.view = viewNode;
});
return {
view: viewRoot,
assets,
}
}
exports.getTree = getTree;
exports.toEgret = execute;
exports.toZeroing = execute$1;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=index.umd.js.map
{"version":3,"file":"index.umd.js","sources":["../src/psd-tree.js","../src/utils.js","../src/egret.js","../src/zeroing.js"],"sourcesContent":["/**\n * Created by rockyl on 2019-08-09.\n */\n\nconst PSD = require('psd');\n\nexport async function getTree(psdFilePath) {\n\tconst psd = await PSD.open(psdFilePath);\n\tconst root = {};\n\twalk(psd.tree(), root);\n\n\treturn root;\n}\n\nfunction walk(psNode, dataNode) {\n\tconst {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};\n\tconst {left, top, width, height, name, layer: {opacity, visible}} = psNode;\n\tconst x = left - pLeft;\n\tconst y = top - pTop;\n\n\tObject.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});\n\tif (psNode.children() && psNode.children().length > 0){\n\t\tdataNode.children = [];\n\t}\n\n\tlet children = psNode.children();\n\tfor (let i = children.length - 1; i >= 0; i--) {\n\t\tconst childPsNode = children[i];\n\n\t\tconst childDataNode = {};\n\t\tdataNode.children.push(childDataNode);\n\t\twalk(childPsNode, childDataNode)\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nexport async function walkNode(node, callback, includeSelf = false) {\n\tif (includeSelf) {\n\t\tawait callback(node, null);\n\t}\n\tif (node.children && node.children.length > 0) {\n\t\tfor (let childNode of node.children) {\n\t\t\tawait callback(childNode, node);\n\t\t\tconst result = await walkNode(childNode, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function walkObject(obj, callback) {\n\tif(typeof obj === \"object\"){\n\t\tfor (let key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tawait callback(key, value, obj);\n\t\t\tconst result = await walkObject(value, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n *\n * 导出exml\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode, walkObject} from \"./utils\";\nimport xml from \"xml\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nconst elementTpls = {\n\t'e:Group': [],\n\t'e:Image': {_attr: {source: '{res}'}},\n\t'e:Button': [\n\t\t{_attr: {label: '{1}',}},\n\t\t{\n\t\t\t'e:skinName': [\n\t\t\t\t{\n\t\t\t\t\t'e:Skin': [\n\t\t\t\t\t\t{_attr: {states: 'up,down,disabled'}},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n};\n\nexport async function execute(psdFile, options) {\n\tconst {skinFilePath, skinClassName, resPath, resGroupName} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tconst exmlRoot = [\n\t\t{\n\t\t\t_attr: {\n\t\t\t\tclass: skinClassName,\n\t\t\t\twidth: tree.width,\n\t\t\t\theight: tree.height,\n\t\t\t\t'xmlns:e': \"http://ns.egret.com/eui\",\n\t\t\t\t'xmlns:w': \"http://ns.egret.com/wing\",\n\t\t\t},\n\t\t},\n\t];\n\tconst exmlData = {\n\t\t'e:Skin': exmlRoot\n\t};\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible} = node;\n\t\tlet attributes = {width, height, alpha, visible};\n\t\tif (x !== 0) {\n\t\t\tattributes.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tattributes.y = y;\n\t\t}\n\t\tlet element;\n\t\tlet tagName;\n\t\tlet imageResName;\n\t\tlet params;\n\n\t\tlet hasChild = node.hasOwnProperty('children');\n\t\tif (hasChild) {\n\t\t\ttagName = 'e:Group';\n\t\t} else {\n\t\t\tconst nameParams = node.name.split('|');\n\t\t\tconst nodeName = nameParams[0];\n\n\t\t\tattributes.name = nodeName;\n\t\t\timageResName = resGroupName + '_' + nodeName;\n\t\t\tconst imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');\n\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\tif (nameParams.length === 1) {\n\t\t\t\ttagName = 'e:Image';\n\t\t\t} else {\n\t\t\t\tparams = nameParams[1].split(',');\n\t\t\t\ttagName = 'e:' + params[0];\n\t\t\t}\n\n\t\t\t//element[tagName] = {_attr: attributes};\n\t\t}\n\n\t\tlet elementTpl = elementTpls[tagName];\n\t\tlet elementContent;\n\t\tif (elementTpl) {\n\t\t\telementContent = JSON.parse(JSON.stringify(elementTpl));\n\t\t} else {\n\t\t\telementContent = {}\n\t\t}\n\t\telement = {\n\t\t\t[tagName]: elementContent,\n\t\t};\n\n\t\tlet attr;\n\t\tif (Array.isArray(elementContent)) {\n\t\t\tattr = elementContent.find(item => item._attr);\n\t\t\tif (!attr) {\n\t\t\t\tattr = {_attr: {}};\n\t\t\t\telementContent.unshift(attr);\n\t\t\t}\n\t\t} else {\n\t\t\tattr = elementContent;\n\t\t}\n\n\t\tObject.assign(attr._attr, attributes);\n\n\t\tif (imageResName) {\n\t\t\tawait walkObject(element, function (key, value, obj) {\n\t\t\t\tif (value === '{res}') {\n\t\t\t\t\tobj[key] = imageResName;\n\t\t\t\t} else if (typeof value === 'string') {\n\t\t\t\t\tconst result = value.match(/{(\\d+)}/g);\n\t\t\t\t\tif(result){\n\t\t\t\t\t\tfor(let item of result){\n\t\t\t\t\t\t\tconst pi = parseInt(item.match(/{(\\d+)}/)[1]);\n\t\t\t\t\t\t\tvalue = value.replace(item, params[pi])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobj[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tif (hasChild) {\n\t\t\tnode.exmlNode = elementContent;\n\t\t}\n\n\t\tconst exmlNode = parent.exmlNode || exmlRoot;\n\t\texmlNode.push(element);\n\t});\n\n\tlet exmlStr = xml(exmlData, {declaration: true, indent: true});\n\tawait fs.ensureDir(path.dirname(skinFilePath));\n\tawait fs.writeFile(skinFilePath, exmlStr);\n\n}","/**\n * Created by rockyl on 2019-09-26.\n *\n * 导出zeroing的视图\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode} from \"./utils\";\nimport path from 'path'\nimport Color from 'color'\nimport generateUUID from 'uuid/v4'\nimport fs from \"fs-extra\";\n\nexport async function execute(psdFile, options) {\n\tconst {\n\t\timagesPath,\n\t} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tlet viewRoot = {\n\t\tname: path.basename(psdFile, '.psd'),\n\t\ttype: 'node',\n\t};\n\n\tconst assets = [];\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;\n\t\tlet properties = {\n\t\t\twidth, height, alpha, visible,\n\t\t};\n\t\tlet viewNode = {\n\t\t\tname: node.name,\n\t\t\tproperties,\n\t\t};\n\t\tif (x !== 0) {\n\t\t\tproperties.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tproperties.y = y;\n\t\t}\n\n\t\tif(typeTool){\n\t\t\tlet fontInfo= typeTool();\n\t\t\tconst fonts = fontInfo.fonts();\n\t\t\tconst styles = fontInfo.styles();\n\t\t\tconst {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;\n\n\t\t\tproperties.text = fontInfo.textValue;\n\t\t\tproperties.textflow = {\n\t\t\t\tfonts, styles, RunLengthArray,\n\t\t\t};\n\t\t\tviewNode.type = 'label';\n\t\t}else if(solidColor){\n\t\t\tconst {r, g, b} = solidColor();\n\t\t\tlet color = Color({r, g, b});\n\n\t\t\tviewNode.type = 'rect';\n\t\t\tproperties.fillColor = '#' + color.rgbNumber().toString(16);\n\t\t}else{\n\t\t\tif(node.hasOwnProperty('children')){\n\t\t\t\tviewNode.type = 'node';\n\t\t\t}else{\n\t\t\t\tviewNode.type = 'image';\n\n\t\t\t\tconst uuid = generateUUID();\n\t\t\t\tconst fileName = Date.now().valueOf();\n\t\t\t\tconst ext = '.png';\n\n\t\t\t\tproperties.source = 'asset|' + uuid;\n\n\t\t\t\tconst imageFilePath = path.join(imagesPath, fileName + ext);\n\t\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\t\tassets.push({\n\t\t\t\t\tname: fileName,\n\t\t\t\t\text,\n\t\t\t\t\tuuid,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tlet viewParent = parent.view || viewRoot;\n\t\tif (!viewParent.hasOwnProperty('children')) {\n\t\t\tviewParent.children = [];\n\t\t}\n\t\tviewParent.children.push(viewNode);\n\n\t\tnode.view = viewNode;\n\t});\n\n\treturn {\n\t\tview: viewRoot,\n\t\tassets,\n\t}\n}\n"],"names":["execute"],"mappings":"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"}
\ No newline at end of file
{
"name": "psd-parse",
"version": "1.0.0",
"main": "dist/index.js",
"license": "MIT",
"dependencies": {
"color": "^3.1.2",
"fs-extra": "^8.1.0",
"psd": "^3.2.0",
"uuid": "^3.3.3",
"xml": "^1.0.1"
},
"scripts": {
"build": "rollup -c"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
/**
* Created by rockyl on 2018/11/16.
*/
const name = 'psd-parse';
export default {
input: 'src/index.js',
output: [
{
file: `dist/index.js`,
format: 'cjs',
sourcemap: true,
},
{
file: `dist/index.es.js`,
format: 'es',
sourcemap: true,
},
{
file: `dist/index.umd.js`,
format: 'umd',
sourcemap: true,
name,
}
],
plugins: [
]
};
{
"version": "0.2.0",
"configurations": [
{
"name": "Wing 内置播放器调试",
"type": "chrome",
"request": "launch",
"file": "index.html",
//"url": "http://mysite.com/index.html",
"runtimeExecutable": "${execPath}",
"sourceMaps": true,
"webRoot": "${workspaceRoot}",
"preLaunchTask":"build",
"port":5773
},
{
"name": "使用本机 Chrome 调试",
"type": "chrome",
"request": "launch",
"file": "index.html",
//"url": "http://mysite.com/index.html",
"runtimeExecutable": "",
"sourceMaps": true,
"webRoot": "${workspaceRoot}",
"preLaunchTask":"build",
"userDataDir":"${tmpdir}",
"port":5773
}
]
}
\ No newline at end of file
{
"version": "0.1.0",
"command": "egret",
"isShellCommand": true,
"tasks": [
{
"taskName": "build",
"showOutput": "always",
"args": [
"build",
"-sourcemap"
],
"problemMatcher": "$tsc"
},
{
"taskName": "clean",
"showOutput": "always",
"args": [
"build",
"-e"
],
"problemMatcher": "$tsc"
},
{
"taskName": "publish",
"showOutput": "always",
"args": [
"publish"
],
"problemMatcher": "$tsc"
}
]
}
\ No newline at end of file
{"/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/design/images/main_p":43863000}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
{
"engineVersion": "5.2.25",
"compilerVersion": "5.2.25",
"template": {},
"target": {
"current": "web"
},
"modules": [
{
"name": "egret"
},
{
"name": "eui"
},
{
"name": "assetsmanager"
},
{
"name": "tween"
},
{
"name": "promise"
}
]
}
\ No newline at end of file
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var xml = _interopDefault(require('xml'));
var path = _interopDefault(require('path'));
var fs = _interopDefault(require('fs-extra'));
/**
* Created by rockyl on 2019-08-09.
*/
const PSD = require('psd');
async function getTree(psdFilePath) {
const psd = await PSD.open(psdFilePath);
const root = {};
walk(psd.tree(), root);
return root;
}
function walk(psNode, dataNode) {
const {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};
const {left, top, width, height, name} = psNode;
const x = left - pLeft;
const y = top - pTop;
Object.assign(dataNode, {x, y, width, height, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});
if (psNode.children() && psNode.children().length > 0){
dataNode.children = [];
}
let children = psNode.children();
for (let i = children.length - 1; i >= 0; i--) {
const childPsNode = children[i];
const childDataNode = {};
dataNode.children.push(childDataNode);
walk(childPsNode, childDataNode);
}
}
/**
* Created by rockyl on 2019-08-10.
*/
async function walkNode(node, callback, includeSelf = false) {
if (includeSelf) {
await callback(node, null);
}
if (node.children && node.children.length > 0) {
for (let childNode of node.children) {
await callback(childNode, node);
const result = await walkNode(childNode, callback);
if (result === true) {
break;
}
}
}
}
async function walkObject(obj, callback) {
if(typeof obj === "object"){
for (let key of Object.keys(obj)) {
const value = obj[key];
await callback(key, value, obj);
const result = await walkObject(value, callback);
if (result === true) {
break;
}
}
}
}
/**
* Created by rockyl on 2019-08-10.
*/
const elementTpls = {
'e:Group': [],
'e:Image': {_attr: {source: '{res}'}},
'e:Button': [
{_attr: {label: '{1}',}},
{
'e:skinName': [
{
'e:Skin': [
{_attr: {states: 'up,down,disabled'}},
{
'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},
},
{
'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},
}
]
}
]
}
]
};
async function execute(psdFile, options) {
const {skinFilePath, skinClassName, resPath, resGroupName} = options;
const tree = await getTree(psdFile);
const exmlRoot = [
{
_attr: {
class: skinClassName,
width: tree.width,
height: tree.height,
'xmlns:e': "http://ns.egret.com/eui",
'xmlns:w': "http://ns.egret.com/wing",
},
},
];
const exmlData = {
'e:Skin': exmlRoot
};
await walkNode(tree, async function (node, parent) {
const {x, y, width, height} = node;
let attributes = {width, height};
if (x !== 0) {
attributes.x = x;
}
if (y !== 0) {
attributes.y = y;
}
let element;
let tagName;
let imageResName;
let params;
let hasChild = node.hasOwnProperty('children');
if (hasChild) {
tagName = 'e:Group';
} else {
const nameParams = node.name.split('|');
const nodeName = nameParams[0];
attributes.name = nodeName;
imageResName = resGroupName + '_' + nodeName;
const imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
if (nameParams.length === 1) {
tagName = 'e:Image';
} else {
params = nameParams[1].split(',');
tagName = 'e:' + params[0];
}
//element[tagName] = {_attr: attributes};
}
let elementTpl = elementTpls[tagName];
let elementContent;
if (elementTpl) {
elementContent = JSON.parse(JSON.stringify(elementTpl));
} else {
elementContent = {};
}
element = {
[tagName]: elementContent,
};
let attr;
if (Array.isArray(elementContent)) {
attr = elementContent.find(item => item._attr);
if (!attr) {
attr = {_attr: {}};
elementContent.unshift(attr);
}
} else {
attr = elementContent;
}
Object.assign(attr._attr, attributes);
if (imageResName) {
await walkObject(element, function (key, value, obj) {
if (value === '{res}') {
obj[key] = imageResName;
} else if (typeof value === 'string') {
const result = value.match(/{(\d+)}/g);
if(result){
for(let item of result){
const pi = parseInt(item.match(/{(\d+)}/)[1]);
value = value.replace(item, params[pi]);
}
obj[key] = value;
}
}
});
}
if (hasChild) {
node.exmlNode = elementContent;
}
const exmlNode = parent.exmlNode || exmlRoot;
exmlNode.push(element);
});
let exmlStr = xml(exmlData, {declaration: true, indent: true});
await fs.ensureDir(path.dirname(skinFilePath));
await fs.writeFile(skinFilePath, exmlStr);
}
/**
* Created by rockyl on 2019-08-08.
*/
/**
* Created by rockyl on 2019-08-10.
*/
(async function generate() {
await execute('psd/test.psd', {
skinFilePath: '/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/resource/eui_skins/MainStageSkin.exml',
skinClassName: 'MainStageSkin',
resPath: '/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/design/images',
resGroupName: 'main',
});
})();
//# sourceMappingURL=generator.cjs.js.map
{"version":3,"file":"generator.cjs.js","sources":["../../src/psd-tree.js","../../src/utils.js","../../src/egret.js","../../src/index.js","generator.js"],"sourcesContent":["/**\n * Created by rockyl on 2019-08-09.\n */\n\nconst PSD = require('psd');\n\nexport async function getTree(psdFilePath) {\n\tconst psd = await PSD.open(psdFilePath);\n\tconst root = {};\n\twalk(psd.tree(), root);\n\n\treturn root;\n}\n\nfunction walk(psNode, dataNode) {\n\tconst {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};\n\tconst {left, top, width, height, name} = psNode;\n\tconst x = left - pLeft;\n\tconst y = top - pTop;\n\n\tObject.assign(dataNode, {x, y, width, height, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});\n\tif (psNode.children() && psNode.children().length > 0){\n\t\tdataNode.children = [];\n\t}\n\n\tlet children = psNode.children();\n\tfor (let i = children.length - 1; i >= 0; i--) {\n\t\tconst childPsNode = children[i];\n\n\t\tconst childDataNode = {};\n\t\tdataNode.children.push(childDataNode);\n\t\twalk(childPsNode, childDataNode)\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nexport async function walkNode(node, callback, includeSelf = false) {\n\tif (includeSelf) {\n\t\tawait callback(node, null);\n\t}\n\tif (node.children && node.children.length > 0) {\n\t\tfor (let childNode of node.children) {\n\t\t\tawait callback(childNode, node);\n\t\t\tconst result = await walkNode(childNode, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function walkObject(obj, callback) {\n\tif(typeof obj === \"object\"){\n\t\tfor (let key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tawait callback(key, value, obj);\n\t\t\tconst result = await walkObject(value, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nimport {getTree} from \"./psd-tree\";\nimport {walkNode, walkObject} from \"./utils\";\nimport xml from \"xml\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nconst elementTpls = {\n\t'e:Group': [],\n\t'e:Image': {_attr: {source: '{res}'}},\n\t'e:Button': [\n\t\t{_attr: {label: '{1}',}},\n\t\t{\n\t\t\t'e:skinName': [\n\t\t\t\t{\n\t\t\t\t\t'e:Skin': [\n\t\t\t\t\t\t{_attr: {states: 'up,down,disabled'}},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n};\n\nexport async function execute(psdFile, options) {\n\tconst {skinFilePath, skinClassName, resPath, resGroupName} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tconst exmlRoot = [\n\t\t{\n\t\t\t_attr: {\n\t\t\t\tclass: skinClassName,\n\t\t\t\twidth: tree.width,\n\t\t\t\theight: tree.height,\n\t\t\t\t'xmlns:e': \"http://ns.egret.com/eui\",\n\t\t\t\t'xmlns:w': \"http://ns.egret.com/wing\",\n\t\t\t},\n\t\t},\n\t];\n\tconst exmlData = {\n\t\t'e:Skin': exmlRoot\n\t};\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height} = node;\n\t\tlet attributes = {width, height};\n\t\tif (x !== 0) {\n\t\t\tattributes.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tattributes.y = y;\n\t\t}\n\t\tlet element;\n\t\tlet tagName;\n\t\tlet imageResName;\n\t\tlet params;\n\n\t\tlet hasChild = node.hasOwnProperty('children');\n\t\tif (hasChild) {\n\t\t\ttagName = 'e:Group';\n\t\t} else {\n\t\t\tconst nameParams = node.name.split('|');\n\t\t\tconst nodeName = nameParams[0];\n\n\t\t\tattributes.name = nodeName;\n\t\t\timageResName = resGroupName + '_' + nodeName;\n\t\t\tconst imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');\n\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\tif (nameParams.length === 1) {\n\t\t\t\ttagName = 'e:Image';\n\t\t\t} else {\n\t\t\t\tparams = nameParams[1].split(',');\n\t\t\t\ttagName = 'e:' + params[0];\n\t\t\t}\n\n\t\t\t//element[tagName] = {_attr: attributes};\n\t\t}\n\n\t\tlet elementTpl = elementTpls[tagName];\n\t\tlet elementContent;\n\t\tif (elementTpl) {\n\t\t\telementContent = JSON.parse(JSON.stringify(elementTpl));\n\t\t} else {\n\t\t\telementContent = {}\n\t\t}\n\t\telement = {\n\t\t\t[tagName]: elementContent,\n\t\t};\n\n\t\tlet attr;\n\t\tif (Array.isArray(elementContent)) {\n\t\t\tattr = elementContent.find(item => item._attr);\n\t\t\tif (!attr) {\n\t\t\t\tattr = {_attr: {}};\n\t\t\t\telementContent.unshift(attr);\n\t\t\t}\n\t\t} else {\n\t\t\tattr = elementContent;\n\t\t}\n\n\t\tObject.assign(attr._attr, attributes);\n\n\t\tif (imageResName) {\n\t\t\tawait walkObject(element, function (key, value, obj) {\n\t\t\t\tif (value === '{res}') {\n\t\t\t\t\tobj[key] = imageResName;\n\t\t\t\t} else if (typeof value === 'string') {\n\t\t\t\t\tconst result = value.match(/{(\\d+)}/g);\n\t\t\t\t\tif(result){\n\t\t\t\t\t\tfor(let item of result){\n\t\t\t\t\t\t\tconst pi = parseInt(item.match(/{(\\d+)}/)[1]);\n\t\t\t\t\t\t\tvalue = value.replace(item, params[pi])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobj[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tif (hasChild) {\n\t\t\tnode.exmlNode = elementContent;\n\t\t}\n\n\t\tconst exmlNode = parent.exmlNode || exmlRoot;\n\t\texmlNode.push(element);\n\t});\n\n\tlet exmlStr = xml(exmlData, {declaration: true, indent: true});\n\tawait fs.ensureDir(path.dirname(skinFilePath));\n\tawait fs.writeFile(skinFilePath, exmlStr);\n\n}","/**\n * Created by rockyl on 2019-08-08.\n */\n\nexport {getTree} from \"./psd-tree\";\nexport {execute as toEgret} from \"./egret\";\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nimport {toEgret} from \"../../src/index\";\n\n(async function generate() {\n\tawait toEgret('psd/test.psd', {\n\t\tskinFilePath: '/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/resource/eui_skins/MainStageSkin.exml',\n\t\tskinClassName: 'MainStageSkin',\n\t\tresPath: '/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/design/images',\n\t\tresGroupName: 'main',\n\t});\n})();\n"],"names":["toEgret"],"mappings":"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"}
\ No newline at end of file
/**
* Created by rockyl on 2019-08-10.
*/
import {toEgret} from "../../src/index";
(async function generate() {
await toEgret('psd/test.psd', {
skinFilePath: '/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/resource/eui_skins/MainStageSkin.exml',
skinClassName: 'MainStageSkin',
resPath: '/Users/rockyl/WorkSpaces/VisualEditor/psd-parse/samples/egret-demo/design/images',
resGroupName: 'main',
});
})();
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Egret</title>
<meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="full-screen" content="true" />
<meta name="screen-orientation" content="portrait" />
<meta name="x5-fullscreen" content="true" />
<meta name="360-fullscreen" content="true" />
<style>
html, body {
-ms-touch-action: none;
background: #888888;
padding: 0;
border: 0;
margin: 0;
height: 100%;
}
</style>
</head>
<body>
<div style="margin: auto;width: 100%;height: 100%;" class="egret-player"
data-entry-class="Main"
data-orientation="auto"
data-scale-mode="showAll"
data-frame-rate="30"
data-content-width="640"
data-content-height="1136"
data-multi-fingered="2"
data-show-fps="false" data-show-log="false"
data-show-fps-style="x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9">
</div>
<script>
var loadScript = function (list, callback) {
var loaded = 0;
var loadNext = function () {
loadSingleScript(list[loaded], function () {
loaded++;
if (loaded >= list.length) {
callback();
}
else {
loadNext();
}
})
};
loadNext();
};
var loadSingleScript = function (src, callback) {
var s = document.createElement('script');
s.async = false;
s.src = src;
s.addEventListener('load', function () {
s.parentNode.removeChild(s);
s.removeEventListener('load', arguments.callee, false);
callback();
}, false);
document.body.appendChild(s);
};
var xhr = new XMLHttpRequest();
xhr.open('GET', './manifest.json?v=' + Math.random(), true);
xhr.addEventListener("load", function () {
var manifest = JSON.parse(xhr.response);
var list = manifest.initial.concat(manifest.game);
loadScript(list, function () {
/**
* {
* "renderMode":, //Engine rendering mode, "canvas" or "webgl"
* "audioType": 0 //Use the audio type, 0: default, 2: web audio, 3: audio
* "antialias": //Whether the anti-aliasing is enabled in WebGL mode, true: on, false: off, defaults to false
* "calculateCanvasScaleFactor": //a function return canvas scale factor
* }
**/
egret.runEgret({ renderMode: "webgl", audioType: 0, calculateCanvasScaleFactor:function(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
}});
});
});
xhr.send(null);
</script>
</body>
</html>
\ No newline at end of file
{
"initial": [
"libs/modules/egret/egret.js",
"libs/modules/egret/egret.web.js",
"libs/modules/eui/eui.js",
"libs/modules/assetsmanager/assetsmanager.js",
"libs/modules/tween/tween.js",
"libs/modules/promise/promise.js"
],
"game": [
"bin-debug/AssetAdapter.js",
"bin-debug/LoadingUI.js",
"bin-debug/Main.js",
"bin-debug/Platform.js",
"bin-debug/ThemeAdapter.js"
]
}
\ No newline at end of file
{
"file": "sheet_main.png",
"frames": {
"main_bg": {
"x": 1,
"y": 1,
"w": 375,
"h": 667,
"offX": 0,
"offY": 0,
"sourceW": 375,
"sourceH": 667
},
"main_hello": {
"x": 378,
"y": 1,
"w": 141,
"h": 50,
"offX": 0,
"offY": 0,
"sourceW": 141,
"sourceH": 50
},
"main_btn0": {
"x": 1,
"y": 670,
"w": 346,
"h": 89,
"offX": 0,
"offY": 0,
"sourceW": 346,
"sourceH": 89
},
"main_btn1": {
"x": 1,
"y": 761,
"w": 346,
"h": 89,
"offX": 0,
"offY": 0,
"sourceW": 346,
"sourceH": 89
}
}
}
\ No newline at end of file
[
"<font color=0x00ff0c>Open-source</font>,<font color=0x00ff0c>Free</font>,<font color=0x00ff0c>Multi-platform</font>",
"Push <font color=0x00ff0c>Game </font>Forward",
"<font color=0x00ff0c>HTML5 </font>Game Engine"
]
\ No newline at end of file
{
"groups": [
{
"keys": "checkbox_select_disabled_png,checkbox_select_down_png,checkbox_select_up_png,checkbox_unselect_png,selected_png,border_png,header_png,radiobutton_select_disabled_png,radiobutton_select_down_png,radiobutton_select_up_png,radiobutton_unselect_png,roundthumb_png,thumb_png,track_png,tracklight_png,handle_png,off_png,on_png,button_down_png,button_up_png,thumb_pb_png,track_pb_png,track_sb_png,bg_jpg,egret_icon_png,description_json",
"name": "preload"
}
],
"resources": [
{
"url": "assets/CheckBox/checkbox_select_disabled.png",
"type": "image",
"name": "checkbox_select_disabled_png"
},
{
"url": "assets/CheckBox/checkbox_select_down.png",
"type": "image",
"name": "checkbox_select_down_png"
},
{
"url": "assets/CheckBox/checkbox_select_up.png",
"type": "image",
"name": "checkbox_select_up_png"
},
{
"url": "assets/CheckBox/checkbox_unselect.png",
"type": "image",
"name": "checkbox_unselect_png"
},
{
"url": "assets/ItemRenderer/selected.png",
"type": "image",
"name": "selected_png"
},
{
"url": "assets/Panel/border.png",
"type": "image",
"name": "border_png"
},
{
"url": "assets/Panel/header.png",
"type": "image",
"name": "header_png"
},
{
"url": "assets/RadioButton/radiobutton_select_disabled.png",
"type": "image",
"name": "radiobutton_select_disabled_png"
},
{
"url": "assets/RadioButton/radiobutton_select_down.png",
"type": "image",
"name": "radiobutton_select_down_png"
},
{
"url": "assets/RadioButton/radiobutton_select_up.png",
"type": "image",
"name": "radiobutton_select_up_png"
},
{
"url": "assets/RadioButton/radiobutton_unselect.png",
"type": "image",
"name": "radiobutton_unselect_png"
},
{
"url": "assets/ScrollBar/roundthumb.png",
"type": "image",
"name": "roundthumb_png"
},
{
"url": "assets/Slider/thumb.png",
"type": "image",
"name": "thumb_png"
},
{
"url": "assets/Slider/track.png",
"type": "image",
"name": "track_png"
},
{
"url": "assets/Slider/tracklight.png",
"type": "image",
"name": "tracklight_png"
},
{
"url": "assets/ToggleSwitch/handle.png",
"type": "image",
"name": "handle_png"
},
{
"url": "assets/ToggleSwitch/off.png",
"type": "image",
"name": "off_png"
},
{
"url": "assets/ToggleSwitch/on.png",
"type": "image",
"name": "on_png"
},
{
"url": "assets/Button/button_down.png",
"type": "image",
"name": "button_down_png"
},
{
"url": "assets/Button/button_up.png",
"type": "image",
"name": "button_up_png"
},
{
"url": "assets/ProgressBar/thumb_pb.png",
"type": "image",
"name": "thumb_pb_png"
},
{
"url": "assets/ProgressBar/track_pb.png",
"type": "image",
"name": "track_pb_png"
},
{
"url": "assets/ScrollBar/track_sb.png",
"type": "image",
"name": "track_sb_png"
},
{
"url": "assets/bg.jpg",
"type": "image",
"name": "bg_jpg"
},
{
"url": "assets/egret_icon.png",
"type": "image",
"name": "egret_icon_png"
},
{
"url": "config/description.json",
"type": "json",
"name": "description_json"
},
{
"url": "assets/sheets/sheet_main.json",
"type": "sheet",
"name": "sheet_main",
"subkeys": "main_bg,main_btn0,main_btn1,main_hello"
}
]
}
\ No newline at end of file
{
"skins": {
"eui.Button": "resource/eui_skins/ButtonSkin.exml",
"eui.CheckBox": "resource/eui_skins/CheckBoxSkin.exml",
"eui.HScrollBar": "resource/eui_skins/HScrollBarSkin.exml",
"eui.HSlider": "resource/eui_skins/HSliderSkin.exml",
"eui.Panel": "resource/eui_skins/PanelSkin.exml",
"eui.TextInput": "resource/eui_skins/TextInputSkin.exml",
"eui.ProgressBar": "resource/eui_skins/ProgressBarSkin.exml",
"eui.RadioButton": "resource/eui_skins/RadioButtonSkin.exml",
"eui.Scroller": "resource/eui_skins/ScrollerSkin.exml",
"eui.ToggleSwitch": "resource/eui_skins/ToggleSwitchSkin.exml",
"eui.VScrollBar": "resource/eui_skins/VScrollBarSkin.exml",
"eui.VSlider": "resource/eui_skins/VSliderSkin.exml",
"eui.ItemRenderer": "resource/eui_skins/ItemRendererSkin.exml"
},
"autoGenerateExmlsList": true,
"exmls": [
"resource/eui_skins/ButtonSkin.exml",
"resource/eui_skins/CheckBoxSkin.exml",
"resource/eui_skins/HScrollBarSkin.exml",
"resource/eui_skins/HSliderSkin.exml",
"resource/eui_skins/ItemRendererSkin.exml",
"resource/eui_skins/PanelSkin.exml",
"resource/eui_skins/ProgressBarSkin.exml",
"resource/eui_skins/RadioButtonSkin.exml",
"resource/eui_skins/ScrollerSkin.exml",
"resource/eui_skins/TextInputSkin.exml",
"resource/eui_skins/ToggleSwitchSkin.exml",
"resource/eui_skins/VScrollBarSkin.exml",
"resource/eui_skins/VSliderSkin.exml"
]
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<e:Skin class="skins.ButtonSkin" states="up,down,disabled" minHeight="50" minWidth="100" xmlns:e="http://ns.egret.com/eui">
<e:Image width="100%" height="100%" scale9Grid="1,3,8,8" alpha.disabled="0.5"
source="button_up_png"
source.down="button_down_png"/>
<e:Label id="labelDisplay" top="8" bottom="8" left="8" right="8"
size="20"
textColor="0xFFFFFF" verticalAlign="middle" textAlign="center"/>
<e:Image id="iconDisplay" horizontalCenter="0" verticalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.CheckBoxSkin" states="up,down,disabled,upAndSelected,downAndSelected,disabledAndSelected" xmlns:e="http://ns.egret.com/eui">
<e:Group width="100%" height="100%">
<e:layout>
<e:HorizontalLayout verticalAlign="middle"/>
</e:layout>
<e:Image fillMode="scale" alpha="1" alpha.disabled="0.5" alpha.down="0.7"
source="checkbox_unselect_png"
source.upAndSelected="checkbox_select_up_png"
source.downAndSelected="checkbox_select_down_png"
source.disabledAndSelected="checkbox_select_disabled_png"/>
<e:Label id="labelDisplay" size="20" textColor="0x707070"
textAlign="center" verticalAlign="middle"
fontFamily="Tahoma"/>
</e:Group>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.HScrollBarSkin" minWidth="20" minHeight="8" xmlns:e="http://ns.egret.com/eui">
<e:Image id="thumb" source="roundthumb_png" scale9Grid="3,3,2,2" height="8" width="30" verticalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.HSliderSkin" minWidth="20" minHeight="8" xmlns:e="http://ns.egret.com/eui">
<e:Image id="track" source="track_sb_png" scale9Grid="1,1,4,4" width="100%"
height="6" verticalCenter="0"/>
<e:Image id="thumb" source="thumb_png" verticalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8" ?>
<e:Skin class="skins.ItemRendererSkin" states="up,down,disabled" minHeight="50" minWidth="100" xmlns:e="http://ns.egret.com/eui">
<e:Image width="100%" height="100%" scale9Grid="1,3,8,8" alpha.disabled="0.5"
source="button_up_png"
source.down="button_down_png"/>
<e:Label id="labelDisplay" top="8" bottom="8" left="8" right="8"
size="20" fontFamily="Tahoma"
textColor="0xFFFFFF" text="{data}" verticalAlign="middle" textAlign="center"/>
</e:Skin>
<?xml version="1.0" encoding="UTF-8"?>
<e:Skin class="MainStageSkin" width="375" height="667" xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing">
<e:Image source="main_bg" width="375" height="667" name="bg"/>
<e:Group width="358" height="228" x="14" y="54">
<e:Button label="button1" width="346" height="89" x="12" y="139" name="btn1">
<e:skinName>
<e:Skin states="up,down,disabled">
<e:Image width="100%" height="100%" source="main_btn1"/>
<e:Label id="labelDisplay" horizontalCenter="0" verticalCenter="0"/>
</e:Skin>
</e:skinName>
</e:Button>
<e:Button label="button0" width="346" height="89" name="btn0">
<e:skinName>
<e:Skin states="up,down,disabled">
<e:Image width="100%" height="100%" source="main_btn0"/>
<e:Label id="labelDisplay" horizontalCenter="0" verticalCenter="0"/>
</e:Skin>
</e:skinName>
</e:Button>
</e:Group>
<e:Image source="main_hello" width="141" height="50" x="104" y="387" name="hello"/>
</e:Skin>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.PanelSkin" minHeight="230" minWidth="450" xmlns:e="http://ns.egret.com/eui">
<e:Image left="0" right="0" bottom="0" top="0" source="border_png" scale9Grid="2,2,12,12" />
<e:Group id="moveArea" left="0" right="0" top="0" height="45">
<e:Image left="0" right="0" bottom="0" top="0" source="header_png"/>
<e:Label id="titleDisplay" size="20" fontFamily="Tahoma" textColor="0xFFFFFF"
wordWrap="false" left="15" right="5" verticalCenter="0"/>
</e:Group>
<e:Button id="closeButton" label="close" bottom="5" horizontalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.ProgressBarSkin" minWidth="30" minHeight="18" xmlns:e="http://ns.egret.com/eui">
<e:Image source="track_pb_png" scale9Grid="1,1,4,4" width="100%"
height="100%" verticalCenter="0"/>
<e:Image id="thumb" height="100%" width="100%" source="thumb_pb_png"/>
<e:Label id="labelDisplay" textAlign="center" verticalAlign="middle"
size="15" fontFamily="Tahoma" textColor="0x707070"
horizontalCenter="0" verticalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.RadioButtonSkin" states="up,down,disabled,upAndSelected,downAndSelected,disabledAndSelected" xmlns:e="http://ns.egret.com/eui">
<e:Group width="100%" height="100%">
<e:layout>
<e:HorizontalLayout verticalAlign="middle"/>
</e:layout>
<e:Image fillMode="scale" alpha="1" alpha.disabled="0.5" alpha.down="0.7"
source="radiobutton_unselect_png"
source.upAndSelected="radiobutton_select_up_png"
source.downAndSelected="radiobutton_select_down_png"
source.disabledAndSelected="radiobutton_select_disabled_png"/>
<e:Label id="labelDisplay" size="20" textColor="0x707070"
textAlign="center" verticalAlign="middle"
fontFamily="Tahoma"/>
</e:Group>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.ScrollerSkin" minWidth="20" minHeight="20" xmlns:e="http://ns.egret.com/eui">
<e:HScrollBar id="horizontalScrollBar" width="100%" bottom="0"/>
<e:VScrollBar id="verticalScrollBar" height="100%" right="0"/>
</e:Skin>
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?>
<e:Skin class="skins.TextInputSkin" minHeight="40" minWidth="300" states="normal,disabled,normalWithPrompt,disabledWithPrompt" xmlns:e="http://ns.egret.com/eui">
<e:Image width="100%" height="100%" scale9Grid="1,3,8,8" source="button_up_png"/>
<e:Rect height="100%" width="100%" fillColor="0xffffff"/>
<e:EditableText id="textDisplay" verticalCenter="0" left="10" right="10"
textColor="0x000000" textColor.disabled="0xff0000" width="100%" height="24" size="20" />
<e:Label id="promptDisplay" verticalCenter="0" left="10" right="10"
textColor="0xa9a9a9" width="100%" height="24" size="20" touchEnabled="false" includeIn="normalWithPrompt,disabledWithPrompt"/>
</e:Skin>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.ToggleSwitchSkin" states="up,down,disabled,upAndSelected,downAndSelected,disabledAndSelected" xmlns:e="http://ns.egret.com/eui">
<e:Image source="on_png"
source.up="off_png"
source.down="off_png"
source.disabled="off_png"/>
<e:Image source="handle_png"
horizontalCenter="-18"
horizontalCenter.upAndSelected="18"
horizontalCenter.downAndSelected="18"
horizontalCenter.disabledAndSelected="18"
verticalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.VScrollBarSkin" minWidth="8" minHeight="20" xmlns:e="http://ns.egret.com/eui">
<e:Image id="thumb" source="roundthumb_png" scale9Grid="3,3,2,2" height="30" width="8" horizontalCenter="0"/>
</e:Skin>
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="skins.VSliderSkin" minWidth="25" minHeight="30" xmlns:e="http://ns.egret.com/eui">
<e:Image id="track" source="track_png" scale9Grid="1,1,4,4" width="7" height="100%" horizontalCenter="0"/>
<e:Image id="thumb" source="thumb_png" horizontalCenter="0" />
</e:Skin>
/**
* ResourceManager 配置文件
*/
type ResourceManagerConfig = {
/**
* 构建与发布配置
*/
buildConfig: (param: BuildConfigParam) => UserConfig,
/**
* 设置资源类型
*/
typeSelector: (path: string) => (string | null | undefined)
/**
* 设置资源的合并策略
*/
mergeSelector?: (path: string) => (string | null | undefined),
/**
* 设置资源的命名策略
* beta 功能,请勿随意使用
*/
nameSelector?: (path: string) => (string | null | undefined)
}
/**
* 构建配置
*/
type UserConfig = {
/**
* 输出路径
*/
outputDir: string,
/**
* 插件
*/
commands: (string | plugins.Command)[]
}
type BuildConfigParam = {
/**
* 当前命令,build 或者 command
*/
readonly command: string;
/**
* 发布平台
*/
readonly target: string;
/**
* 开发者指定的版本号
*/
readonly version: string;
/**
* 项目名称
*/
readonly projectName: string;
/**
* 项目路径
*/
readonly projectRoot: string;
/**
* 项目配置
*/
readonly projectConfig: ProjectConfig;
}
type ProjectConfig = {
entryClassName: string;
orientation: string;
frameRate: number;
scaleMode: string;
contentWidth: number;
contentHeight: number;
showFPS: boolean;
fpsStyles: string;
showLog: boolean;
maxTouches: number;
}
/**
* 匹配机制,将满足 from 的文件输出为 to 格式的文件
* from 采用 glob 表达式 , to 包含 [path][name][hash][ext]四个变量
* 示例:{ from:"resource/**.*" , to:"[path][name]_[hash].[ext]" }
*/
type Matcher = {
from: string,
to: string
}
declare namespace plugins {
interface CommandContext {
/**
* 可以用此接口进行文件创建
*/
createFile(relativeFilePath: string, contents: Buffer);
/**
* 构建配置
*/
buildConfig: BuildConfigParam;
/**
* 项目绝对路径
*/
projectRoot: string;
/**
* 项目输出绝对路径
*/
outputDir: string;
}
/**
* 构建管线命令
*/
interface Command {
/**
* 项目中的每个文件都会执行此函数,返回 file 表示保留此文件,返回 null 表示将此文件从构建管线中删除,即不会发布
*/
onFile?(file: File): Promise<File | null>
/**
* 项目中所有文件均执行完后,最终会执行此函数。
* 这个函数主要被用于创建新文件
*/
onFinish?(pluginContext?: CommandContext): Promise<void>
[options: string]: any;
}
interface File {
/**
* 文件内容的二进制流,如果开发者需要修改文件内容,请修改此属性
*/
contents: Buffer;
/**
* 文件绝对路径,如果开发者需要对文件进行重命名,请修改此属性
*/
path: string;
/**
* 文件所在的项目的项目路径
*/
readonly base: string;
/**
* 文件的相对于 base 属性的相对路径
*/
readonly relative: string;
/**
* 文件变更历史,history[0] 即 origin 属性
*/
readonly history: ReadonlyArray<string>;
/**
* 文件所在的文件夹的绝对路径
*/
readonly dirname: string;
/**
* 文件的文件名
*/
readonly basename: string;
/**
* 文件的扩展名
*/
readonly extname: string;
/**
* 文件的初始文件名
*/
readonly origin: string;
/**
* 其他自定义属性
*/
[customProperty: string]: any;
}
}
declare module 'built-in' {
/**
* 混淆插件参数,设置源代码和目标代码
*/
type UglifyPluginOption = { sources: string[], target: string };
type UglifyPluginOptions = UglifyPluginOption[];
/**
* 混淆插件
*/
export class UglifyPlugin implements plugins.Command {
constructor(mergeSelector: UglifyPluginOptions);
}
type LibraryType = "debug" | "release";
type CompilePluginOptions = { libraryType: LibraryType, defines?: any };
/**
* 编译命令
*/
export class CompilePlugin implements plugins.Command {
constructor(options: CompilePluginOptions);
}
/**
* EXML 插件,用于发布 EXML 文件
*/
export class ExmlPlugin implements plugins.Command {
constructor(publishPolicy: EXML_Publish_Policy);
}
/**
* 发布策略
* * debug : 默认策略,用于开发环境
* * contents : 将 EXML 的内容写入到主题文件中
* * gjs : 将生成的JS文件写入到主题文件中
* * commonjs : 将EXML合并为一个 CommonJS 风格的文件
* * commonjs2 : 将EXML合并为一个含有解析方法和皮肤定义的文件,且皮肤抽离为一份配置
* * json : 将每个EXML文件生成一份配置
*/
type EXML_Publish_Policy = "debug" | "contents" | "gjs" | "commonjs" | "commonjs2" | "json"
/**
* 生成 manifest 文件,这个文件会被用于记录 JavaScript 文件的版本号
*/
export class ManifestPlugin implements plugins.Command {
constructor(options?: ManifestPluginOptions)
}
/**
* 生成文件的文件名
* 支持 json 与 js 两种格式
*/
type ManifestPluginOptions = {
output: string,
hash?: "crc32",
/**
* 是否输出转换过程
*/
verbose?: boolean,
/**
* 其他传递的消息参数
*/
info?:any
}
/**
* EmitResConfigFilePlugin 的参数
* * output: 生成路径,可以指定生成为 *.res.js 文件或者 *.res.json 文件
* * typeSelector: 根据文件路径决定文件类型
* * nameSelector: 根据文件路径决定文件的资源名
* * groupSelector: 根据文件路径决定资源所述的资源组
*/
type EmitResConfigFilePluginOptions = {
output: string,
typeSelector: (path: string) => string | null | undefined,
nameSelector: (path: string) => string | null | undefined,
groupSelector: (path: string) => string | null | undefined,
}
/**
* 生成 res.json 文件或者 res.js 文件
*/
export class EmitResConfigFilePlugin implements plugins.Command {
constructor(options: EmitResConfigFilePluginOptions)
}
export type ConvertResourceConfigPluginOption = {
resourceConfigFiles: { filename: string, root: string }[];
nameSelector: (url: string) => string;
TM_Verbose: boolean;
}
export class ConvertResConfigFilePlugin implements plugins.Command {
constructor(options: ConvertResourceConfigPluginOption);
}
/**
* 增量编译
* 这个插件生成的 JavaScript 代码不会被添加到构建管线中,后续其他插件无法获取生成的 js 文件
* 这个功能将会在未来被 watch 模式代替掉
*/
export class IncrementCompilePlugin implements plugins.Command {
}
type TextureMergerOptions = {
textureMergerRoot: string[];
}
/**
* 使用 TextureMerger 实现纹理自动合并,依赖 TextureMerger 1.7 以上的版本
*/
export class TextureMergerPlugin implements plugins.Command {
constructor(options: TextureMergerOptions);
}
type CleanPluginOptions = {
matchers: string[]
}
export class CleanPlugin implements plugins.Command {
constructor(options: CleanPluginOptions);
}
type RenamePluginOptions = {
/**
* 是否输出日志
* Whether to output the log
*/
verbose?: boolean
/**
* 采用何种 hash 算法,目前暂时只支持 crc32
* What hash algorithm is used, currently only crc32 is supported
*/
hash?: "crc32"
/**
* 设置匹配规则,将指定文件进行改名
* 该参数是个数组,允许设置多个匹配规则
* Set up matching rules to copy specified files to other folders
* This parameter is an array that allows multiple matching rules to be set
*/
matchers: Matcher[]
/**
* 回调函数,返回值里包括文件的一些信息
* The callback function, return value includes some information about the file
*/
callback?: Function
}
/**
* 修改文件名插件
*/
export class RenamePlugin implements plugins.Command {
constructor(options: RenamePluginOptions);
}
type ResSplitPluginOptions = {
/**
* 是否输出日志
* Whether to output the log
*/
verbose?: boolean
/**
* 设置匹配规则,将指定文件拷贝至其他文件夹
* 该参数是个数组,允许设置多个匹配规则
* Set up matching rules to copy specified files to other folders
* This parameter is an array that allows multiple matching rules to be set
*/
matchers: Matcher[]
}
export class ResSplitPlugin implements plugins.Command {
constructor(options: ResSplitPluginOptions);
}
type ZipPluginOptions = {
mergeSelector: (p: string) => string
}
export class ZipPlugin implements plugins.Command {
constructor(option: ZipPluginOptions);
}
type MergeEuiJsonPluginOptions = {
mergeSelector?: (p: string) => string | null,
createConfig?: boolean
}
export class MergeEuiJsonPlugin implements plugins.Command {
constructor(option?: MergeEuiJsonPluginOptions);
}
}
import * as fs from 'fs';
import * as path from 'path';
export class BaidugamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布百度小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "game.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}
\ No newline at end of file
import * as fs from 'fs';
import * as path from 'path';
type ManifestConfig = {
initial: string[],
game: string[]
}
export class BricksPlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
const filename = file.basename;
if (filename == 'manifest.json') {
const contents = file.contents.toString();
const jsonData: ManifestConfig = JSON.parse(contents);
let content = '';
content += `BK.Script.loadlib("GameRes://js/promise.js");\n`;
for (let item of jsonData.initial) {
if (item != 'js/promise.js' && item != 'js/promise.min.js') {
content += `BK.Script.loadlib("GameRes://${item}");\n`
}
}
for (let item of jsonData.game) {
content += `BK.Script.loadlib("GameRes://${item}");\n`
}
content += `BK.Script.loadlib("GameRes://egret.bricks.js");\n`
file.path = file.dirname + '/manifest.js'
file.contents = new Buffer(content);
} else if (filename == 'main.js') {
const content = file.contents.toString();
let result = content.replace(/RES\.loadConfig\("resource\/default\.res\.json", "resource\/"\)/gm, 'RES.loadConfig("GameRes://resource/default.res.json", "GameRes://resource/")');
result = result.replace(/eui\.Theme\("resource\/default\.thm\.json", _this\.stage\)/gm, 'eui.Theme("GameRes://resource/default.thm.json", _this.stage)');
result += ";global.Main = Main;";
file.path = file.dirname + '/main.js'
file.contents = new Buffer(result);
} else if (filename == 'promise.js') {
return null;
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步index.html 配置到main.js
let mainJSPath = path.join(pluginContext.outputDir, 'main.js');
let mainJSContent = fs.readFileSync(mainJSPath, { encoding: "utf8" });
let projectConfig = pluginContext.buildConfig.projectConfig;
mainJSContent = mainJSContent.replace(/frameRate: 30/gm, `frameRate: ${projectConfig.frameRate}`);
mainJSContent = mainJSContent.replace(/contentWidth: 640/gm, `contentWidth: ${projectConfig.contentWidth}`);
mainJSContent = mainJSContent.replace(/contentHeight: 1136/gm, `contentHeight: ${projectConfig.contentHeight}`);
mainJSContent = mainJSContent.replace(/entryClassName: "Main"/gm, `entryClassName: ${projectConfig.entryClassName}`);
mainJSContent = mainJSContent.replace(/scaleMode: "showAll"/gm, `scaleMode: ${projectConfig.scaleMode}`);
mainJSContent = mainJSContent.replace(/orientation: "auto"/gm, `orientation: ${projectConfig.orientation}`);
fs.writeFileSync(mainJSPath, mainJSContent);
}
}
declare var egret;
\ No newline at end of file
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_android/assets/game`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { BaidugamePlugin } from './baidugame/baidugame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_baidugame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new BaidugamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new BaidugamePlugin(),
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { BricksPlugin } from './bricks/bricks';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_bricks/PublicBrickEngineGame/Res`;
if (command == 'build') {
return {
outputDir,
commands: [
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' }),
new BricksPlugin()
]
}
}
else if (command == 'publish') {
console.log('执行publish')
return {
outputDir,
commands: [
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' }),
new UglifyPlugin([{
sources: ["main.js"],
target: "js/main.min.js"
}
]),
new BricksPlugin(),
]
}
} else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_ios/assets/game`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, ResSplitPlugin, CleanPlugin } from 'built-in';
import { OppogamePlugin } from './oppogame/oppogame';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_oppogame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new OppogamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new OppogamePlugin(),
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, ResSplitPlugin, CleanPlugin } from 'built-in';
import { MiqgamePlugin } from './qgame/qgame';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_qgame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new MiqgamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new MiqgamePlugin(),
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { QQgamePlugin } from './qqgame/qqgame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_qqgame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new QQgamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new QQgamePlugin(),
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, IncrementCompilePlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, RenamePlugin } from 'built-in';
import { WxgamePlugin } from './wxgame/wxgame';
import { BricksPlugin } from './bricks/bricks';
import { CustomPlugin } from './myplugin';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
if (command == 'build') {
const outputDir = '.';
return {
outputDir,
commands: [
// new EmitResConfigFilePlugin({
// output: "resource/default.res.json",
// typeSelector: config.typeSelector,
// nameSelector: p => path.basename(p).replace(/\./gi, "_"),
// groupSelector: p => "preload"
// }),
new ExmlPlugin('debug'), // 非 EUI 项目关闭此设置
new IncrementCompilePlugin(),
]
}
}
else if (command == 'publish') {
const outputDir = `bin-release/web/${version}`;
return {
outputDir,
commands: [
new CustomPlugin(),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}]),
new RenamePlugin({
verbose: true, hash: 'crc32', matchers: [
{ from: "**/*.js", to: "[path][name]_[hash].[ext]" }
]
}),
new ManifestPlugin({ output: "manifest.json" })
]
}
}
else {
throw `unknown command : ${params.command}`
}
},
mergeSelector: (path) => {
if (path.indexOf("assets/bitmap/") >= 0) {
return "assets/bitmap/sheet.sheet"
}
else if (path.indexOf("armature") >= 0 && path.indexOf(".json") >= 0) {
return "assets/armature/1.zip";
}
},
typeSelector: (path) => {
const ext = path.substr(path.lastIndexOf(".") + 1);
const typeMap = {
"jpg": "image",
"png": "image",
"webp": "image",
"json": "json",
"fnt": "font",
"pvr": "pvr",
"mp3": "sound",
"zip": "zip",
"sheet": "sheet",
"exml": "text"
}
let type = typeMap[ext];
if (type == "json") {
if (path.indexOf("sheet") >= 0) {
type = "sheet";
} else if (path.indexOf("movieclip") >= 0) {
type = "movieclip";
};
}
return type;
}
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, ResSplitPlugin, CleanPlugin } from 'built-in';
import { VivogamePlugin } from './vivogame/vivogame';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_vivogame/src`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["../engine", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new VivogamePlugin(),
new ManifestPlugin({ output: 'manifest.js', info: { target: 'vivogame' } })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["../engine", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new VivogamePlugin(),
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js', info: { target: 'vivogame' } })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { WxgamePlugin } from './wxgame/wxgame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_wxgame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new WxgamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new WxgamePlugin(),
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;
/**
* 示例自定义插件,您可以查阅 http://developer.egret.com/cn/github/egret-docs/Engine2D/projectConfig/cmdExtensionPlugin/index.html
* 了解如何开发一个自定义插件
*/
export class CustomPlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
return file;
}
async onFinish(commandContext: plugins.CommandContext) {
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
import * as fs from 'fs';
import * as path from 'path';
export class OppogamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
if(filename == "libs/modules/eui/eui.js"){
content = content.replace("function getRepeatedIds","window.getRepeatedIds=function getRepeatedIds");
content = content.replace("function getIds","window.getIds=function getIds");
content = content.replace("function toXMLString","window.toXMLString=function toXMLString");
content = content.replace("function checkDeclarations","window.checkDeclarations=function checkDeclarations");
content = content.replace("function getPropertyStr","window.getPropertyStr=function getPropertyStr");
}
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "main.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布Oppo快游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "manifest.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.orientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}
import * as fs from 'fs';
import * as path from 'path';
export class MiqgamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
if(filename == "libs/modules/eui/eui.js"){
content = content.replace("function getRepeatedIds","window.getRepeatedIds=function getRepeatedIds");
content = content.replace("function getIds","window.getIds=function getIds");
content = content.replace("function toXMLString","window.toXMLString=function toXMLString");
content = content.replace("function checkDeclarations","window.checkDeclarations=function checkDeclarations");
content = content.replace("function getPropertyStr","window.getPropertyStr=function getPropertyStr");
}
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "main.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布小米快游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "manifest.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.orientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}
import * as fs from 'fs';
import * as path from 'path';
export class QQgamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布QQ小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "game.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}
\ No newline at end of file
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
"lib": [
"es5",
"es2015.promise"
], /* Specify library files to be included in the compilation: */
"allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
/* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
/* Source Map Options */
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}
}
\ No newline at end of file
import * as fs from 'fs';
import * as path from 'path';
export class VivogamePlugin implements plugins.Command {
jsFileList: any = []
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
this.jsFileList.push(file.basename)
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
if (filename == "libs/modules/eui/eui.js") {
content = content.replace("function getRepeatedIds", "window.getRepeatedIds=function getRepeatedIds");
content = content.replace("function getIds", "window.getIds=function getIds");
content = content.replace("function toXMLString", "window.toXMLString=function toXMLString");
content = content.replace("function checkDeclarations", "window.checkDeclarations=function checkDeclarations");
content = content.replace("function getPropertyStr", "window.getPropertyStr=function getPropertyStr");
}
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if (!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布 Vivo 小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "manifest.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
let isPublish = pluginContext.buildConfig.command == "publish" ? true : false;
let configOption = "webpackConf.externals = Object.assign(webpackConf.externals || {\n\t\t"
for (var i = 0, len = this.jsFileList.length; i < len; i++) {
let jsFile = this.jsFileList[i];
if(isPublish && jsFile == "main.js"){
jsFile = 'main.min.js'
}
configOption += `"js/${jsFile}":"commonjs js/${jsFile}"`
if (i < len - 1) {
configOption += ",\n\t\t"
} else {
configOption += "\n\t\t"
}
}
configOption += "})"
const replaceConfigStr = '\/\/----auto option start----\n\t\t' + configOption + '\n\t\t\/\/----auto option end----';
const webpackConfigPath = path.join(pluginContext.outputDir, '../config', "webpack.config.js");
let configJSContent = fs.readFileSync(webpackConfigPath, { encoding: "utf8" });
configJSContent = configJSContent.replace(reg, replaceConfigStr);
fs.writeFileSync(webpackConfigPath, configJSContent);
}
}
import * as fs from 'fs';
import * as path from 'path';
export class WxgamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布微信小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "game.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}
\ No newline at end of file
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
class AssetAdapter implements eui.IAssetAdapter {
/**
* @language zh_CN
* 解析素材
* @param source 待解析的新素材标识符
* @param compFunc 解析完成回调函数,示例:callBack(content:any,source:string):void;
* @param thisObject callBack的 this 引用
*/
public getAsset(source: string, compFunc:Function, thisObject: any): void {
function onGetRes(data: any): void {
compFunc.call(thisObject, data, source);
}
if (RES.hasRes(source)) {
let data = RES.getRes(source);
if (data) {
onGetRes(data);
}
else {
RES.getResAsync(source, onGetRes, this);
}
}
else {
RES.getResByUrl(source, onGetRes, this, RES.ResourceItem.TYPE_IMAGE);
}
}
}
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
class LoadingUI extends egret.Sprite implements RES.PromiseTaskReporter {
public constructor() {
super();
this.createView();
}
private textField: egret.TextField;
private createView(): void {
this.textField = new egret.TextField();
this.addChild(this.textField);
this.textField.y = 300;
this.textField.width = 480;
this.textField.height = 100;
this.textField.textAlign = "center";
}
public onProgress(current: number, total: number): void {
this.textField.text = `Loading...${current}/${total}`;
}
}
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
class Main extends eui.UILayer {
protected createChildren(): void {
super.createChildren();
egret.lifecycle.addLifecycleListener((context) => {
// custom lifecycle plugin
})
egret.lifecycle.onPause = () => {
egret.ticker.pause();
}
egret.lifecycle.onResume = () => {
egret.ticker.resume();
}
//inject the custom material parser
//注入自定义的素材解析器
let assetAdapter = new AssetAdapter();
egret.registerImplementation("eui.IAssetAdapter", assetAdapter);
egret.registerImplementation("eui.IThemeAdapter", new ThemeAdapter());
this.runGame().catch(e => {
console.log(e);
})
}
private async runGame() {
await this.loadResource()
this.createGameScene();
const result = await RES.getResAsync("description_json")
this.startAnimation(result);
await platform.login();
const userInfo = await platform.getUserInfo();
console.log(userInfo);
}
private async loadResource() {
try {
const loadingView = new LoadingUI();
this.stage.addChild(loadingView);
await RES.loadConfig("resource/default.res.json", "resource/");
await this.loadTheme();
await RES.loadGroup("preload", 0, loadingView);
this.stage.removeChild(loadingView);
}
catch (e) {
console.error(e);
}
}
private loadTheme() {
return new Promise((resolve, reject) => {
// load skin theme configuration file, you can manually modify the file. And replace the default skin.
//加载皮肤主题配置文件,可以手动修改这个文件。替换默认皮肤。
let theme = new eui.Theme("resource/default.thm.json", this.stage);
theme.addEventListener(eui.UIEvent.COMPLETE, () => {
resolve();
}, this);
})
}
private textfield: egret.TextField;
/**
* 创建场景界面
* Create scene interface
*/
protected createGameScene(): void {
let sky = this.createBitmapByName("bg_jpg");
this.addChild(sky);
let stageW = this.stage.stageWidth;
let stageH = this.stage.stageHeight;
sky.width = stageW;
sky.height = stageH;
let topMask = new egret.Shape();
topMask.graphics.beginFill(0x000000, 0.5);
topMask.graphics.drawRect(0, 0, stageW, 172);
topMask.graphics.endFill();
topMask.y = 33;
this.addChild(topMask);
let icon: egret.Bitmap = this.createBitmapByName("egret_icon_png");
this.addChild(icon);
icon.x = 26;
icon.y = 33;
let line = new egret.Shape();
line.graphics.lineStyle(2, 0xffffff);
line.graphics.moveTo(0, 0);
line.graphics.lineTo(0, 117);
line.graphics.endFill();
line.x = 172;
line.y = 61;
this.addChild(line);
let colorLabel = new egret.TextField();
colorLabel.textColor = 0xffffff;
colorLabel.width = stageW - 172;
colorLabel.textAlign = "center";
colorLabel.text = "Hello Egret";
colorLabel.size = 24;
colorLabel.x = 172;
colorLabel.y = 80;
this.addChild(colorLabel);
let textfield = new egret.TextField();
this.addChild(textfield);
textfield.alpha = 0;
textfield.width = stageW - 172;
textfield.textAlign = egret.HorizontalAlign.CENTER;
textfield.size = 24;
textfield.textColor = 0xffffff;
textfield.x = 172;
textfield.y = 135;
this.textfield = textfield;
let button = new eui.Button();
button.label = "Click!";
button.horizontalCenter = 0;
button.verticalCenter = 0;
this.addChild(button);
button.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onButtonClick, this);
}
/**
* 根据name关键字创建一个Bitmap对象。name属性请参考resources/resource.json配置文件的内容。
* Create a Bitmap object according to name keyword.As for the property of name please refer to the configuration file of resources/resource.json.
*/
private createBitmapByName(name: string): egret.Bitmap {
let result = new egret.Bitmap();
let texture: egret.Texture = RES.getRes(name);
result.texture = texture;
return result;
}
/**
* 描述文件加载成功,开始播放动画
* Description file loading is successful, start to play the animation
*/
private startAnimation(result: Array<any>): void {
let parser = new egret.HtmlTextParser();
let textflowArr = result.map(text => parser.parse(text));
let textfield = this.textfield;
let count = -1;
let change = () => {
count++;
if (count >= textflowArr.length) {
count = 0;
}
let textFlow = textflowArr[count];
// 切换描述内容
// Switch to described content
textfield.textFlow = textFlow;
let tw = egret.Tween.get(textfield);
tw.to({ "alpha": 1 }, 200);
tw.wait(2000);
tw.to({ "alpha": 0 }, 200);
tw.call(change, this);
};
change();
}
/**
* 点击按钮
* Click the button
*/
private onButtonClick(e: egret.TouchEvent) {
let panel = new eui.Panel();
panel.title = "Title";
panel.horizontalCenter = 0;
panel.verticalCenter = 0;
this.addChild(panel);
}
}
/**
* 平台数据接口。
* 由于每款游戏通常需要发布到多个平台上,所以提取出一个统一的接口用于开发者获取平台数据信息
* 推荐开发者通过这种方式封装平台逻辑,以保证整体结构的稳定
* 由于不同平台的接口形式各有不同,白鹭推荐开发者将所有接口封装为基于 Promise 的异步形式
*/
declare interface Platform {
getUserInfo(): Promise<any>;
login(): Promise<any>
}
class DebugPlatform implements Platform {
async getUserInfo() {
return { nickName: "username" }
}
async login() {
}
}
if (!window.platform) {
window.platform = new DebugPlatform();
}
declare let platform: Platform;
declare interface Window {
platform: Platform
}
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
class ThemeAdapter implements eui.IThemeAdapter {
/**
* 解析主题
* @param url 待解析的主题url
* @param onSuccess 解析完成回调函数,示例:compFunc(e:egret.Event):void;
* @param onError 解析失败回调函数,示例:errorFunc():void;
* @param thisObject 回调的this引用
*/
public getTheme(url: string, onSuccess: Function, onError: Function, thisObject: any): void {
function onResGet(e: string): void {
onSuccess.call(thisObject, e);
}
function onResError(e: RES.ResourceEvent): void {
if (e.resItem.url == url) {
RES.removeEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, onResError, null);
onError.call(thisObject);
}
}
if (typeof generateEUI !== 'undefined') {
egret.callLater(() => {
onSuccess.call(thisObject, generateEUI);
}, this);
}
else if (typeof generateEUI2 !== 'undefined') {
RES.getResByUrl("resource/gameEui.json", (data, url) => {
window["JSONParseClass"]["setData"](data);
egret.callLater(() => {
onSuccess.call(thisObject, generateEUI2);
}, this);
}, this, RES.ResourceItem.TYPE_JSON);
}
else if (typeof generateJSON !== 'undefined') {
if (url.indexOf(".exml") > -1) {
let dataPath = url.split("/");
dataPath.pop();
let dirPath = dataPath.join("/") + "_EUI.json";
if (!generateJSON.paths[url]) {
RES.getResByUrl(dirPath, (data) => {
window["JSONParseClass"]["setData"](data);
egret.callLater(() => {
onSuccess.call(thisObject, generateJSON.paths[url]);
}, this);
}, this, RES.ResourceItem.TYPE_JSON);
} else {
egret.callLater(() => {
onSuccess.call(thisObject, generateJSON.paths[url]);
}, this);
}
}
else {
egret.callLater(() => {
onSuccess.call(thisObject, generateJSON);
}, this);
}
}
else {
RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, onResError, null);
RES.getResByUrl(url, onResGet, this, RES.ResourceItem.TYPE_TEXT);
}
}
}
declare var generateEUI: { paths: string[], skins: any }
declare var generateEUI2: { paths: string[], skins: any }
declare var generateJSON: { paths: string[], skins: any }
\ No newline at end of file
require("launcher/native_require.js");
egret_native.egtMain = function () {
egret_native.nativeType = "native";
egret_native.egretInit();
egret_native.egretStart();
};
var manifest = JSON.parse(egret_native.readFileSync("manifest.json"));
var game_file_list = manifest.initial.concat(manifest.game);
var window = this;
egret_native.setSearchPaths([""]);
egret_native.requireFiles = function () {
for (var key in game_file_list) {
var src = game_file_list[key];
require(src);
}
};
egret_native.egretInit = function () {
if(egret_native.featureEnable) {
//控制一些优化方案是否开启
//Control whether some optimization options are open
var result = egret_native.featureEnable({
});
}
egret_native.requireFiles();
egret.dom = {};
egret.dom.drawAsCanvas = function () {
};
};
egret_native.egretStart = function () {
var option = {
//以下为自动修改,请勿修改
//The following is automatically modified, please do not modify
//----auto option start----
//----auto option end----
};
egret.native.NativePlayer.option = option;
egret.runEgret();
egret_native.Label.createLabel("/system/fonts/DroidSansFallback.ttf", 20, "", 0);
egret_native.EGTView.preSetOffScreenBufferEnable(true);
};
\ No newline at end of file
require("launcher/native_require.js");
egret_native.egtMain = function () {
egret_native.nativeType = "runtime";
egret_native.egretInit();
egret_native.egretStart();
};
\ No newline at end of file
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Egret</title>
<meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="full-screen" content="true" />
<meta name="screen-orientation" content="portrait" />
<meta name="x5-fullscreen" content="true" />
<meta name="360-fullscreen" content="true" />
<style>
html, body {
-ms-touch-action: none;
background: #888888;
padding: 0;
border: 0;
margin: 0;
height: 100%;
}
</style>
</head>
<body>
<div style="margin: auto;width: 100%;height: 100%;" class="egret-player"
data-entry-class="Main"
data-orientation="auto"
data-scale-mode="showAll"
data-frame-rate="30"
data-content-width="640"
data-content-height="1136"
data-show-paint-rect="false"
data-multi-fingered="2"
data-show-fps="false" data-show-log="false"
data-show-fps-style="x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9">
</div>
<script>
var loadScript = function (list, callback) {
var loaded = 0;
var loadNext = function () {
loadSingleScript(list[loaded], function () {
loaded++;
if (loaded >= list.length) {
callback();
}
else {
loadNext();
}
})
};
loadNext();
};
var loadSingleScript = function (src, callback) {
var s = document.createElement('script');
s.async = false;
s.src = src;
s.addEventListener('load', function () {
s.parentNode.removeChild(s);
s.removeEventListener('load', arguments.callee, false);
callback();
}, false);
document.body.appendChild(s);
};
var xhr = new XMLHttpRequest();
xhr.open('GET', './manifest.json?v=' + Math.random(), true);
xhr.addEventListener("load", function () {
var manifest = JSON.parse(xhr.response);
var list = manifest.initial.concat(manifest.game);
loadScript(list, function () {
/**
* {
* "renderMode":, //Engine rendering mode, "canvas" or "webgl"
* "audioType": 0 //Use the audio type, 0: default, 2: web audio, 3: audio
* "antialias": //Whether the anti-aliasing is enabled in WebGL mode, true: on, false: off, defaults to false
* "calculateCanvasScaleFactor": //a function return canvas scale factor
* }
**/
egret.runEgret({ renderMode: "webgl", audioType: 0, calculateCanvasScaleFactor:function(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
}});
});
});
xhr.send(null);
</script>
</body>
</html>
\ No newline at end of file
{
"compilerOptions": {
"target": "es5",
"outDir": "bin-debug",
"experimentalDecorators": true,
"lib": [
"es5",
"dom",
"es2015.promise"
],
"types": []
},
"include": [
"src",
"libs"
]
}
\ No newline at end of file
{
"resourcePlugin":{
"configs":[{
"configPath":"resource/default.res.json",
"relativePath":"resource/"
}]
},
"theme":"resource/default.thm.json"
}
\ No newline at end of file
{
"name": "samples",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"egret": "rollup -i egret-demo/generator.js -o egret-demo/generator.cjs.js -f cjs -m&&node egret-demo/generator.cjs.js",
"zeroing": "rollup -i zeroing-demo/generator.js -o zeroing-demo/generator.cjs.js -f cjs -m&&node zeroing-demo/generator.cjs.js"
}
}
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
require('xml');
var path = _interopDefault(require('path'));
var fs = _interopDefault(require('fs-extra'));
var Color = _interopDefault(require('color'));
var generateUUID = _interopDefault(require('uuid/v4'));
/**
* Created by rockyl on 2019-08-09.
*/
const PSD = require('psd');
async function getTree(psdFilePath) {
const psd = await PSD.open(psdFilePath);
const root = {};
walk(psd.tree(), root);
return root;
}
function walk(psNode, dataNode) {
const {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};
const {left, top, width, height, name, layer: {opacity, visible}} = psNode;
const x = left - pLeft;
const y = top - pTop;
Object.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});
if (psNode.children() && psNode.children().length > 0){
dataNode.children = [];
}
let children = psNode.children();
for (let i = children.length - 1; i >= 0; i--) {
const childPsNode = children[i];
const childDataNode = {};
dataNode.children.push(childDataNode);
walk(childPsNode, childDataNode);
}
}
/**
* Created by rockyl on 2019-08-10.
*/
async function walkNode(node, callback, includeSelf = false) {
if (includeSelf) {
await callback(node, null);
}
if (node.children && node.children.length > 0) {
for (let childNode of node.children) {
await callback(childNode, node);
const result = await walkNode(childNode, callback);
if (result === true) {
break;
}
}
}
}
/**
* Created by rockyl on 2019-09-26.
*
* 导出zeroing的视图
*/
async function execute$1(psdFile, options) {
const {
imagesPath,
} = options;
const tree = await getTree(psdFile);
let viewRoot = {
name: path.basename(psdFile, '.psd'),
type: 'node',
};
const assets = [];
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;
let properties = {
width, height, alpha, visible,
};
let viewNode = {
name: node.name,
properties,
};
if (x !== 0) {
properties.x = x;
}
if (y !== 0) {
properties.y = y;
}
if(typeTool){
let fontInfo= typeTool();
const fonts = fontInfo.fonts();
const styles = fontInfo.styles();
const {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;
properties.text = fontInfo.textValue;
properties.textflow = {
fonts, styles, RunLengthArray,
};
viewNode.type = 'label';
}else if(solidColor){
const {r, g, b} = solidColor();
let color = Color({r, g, b});
viewNode.type = 'rect';
properties.fillColor = '#' + color.rgbNumber().toString(16);
}else{
if(node.hasOwnProperty('children')){
viewNode.type = 'node';
}else{
viewNode.type = 'image';
const uuid = generateUUID();
const fileName = Date.now().valueOf();
const ext = '.png';
properties.source = 'asset|' + uuid;
const imageFilePath = path.join(imagesPath, fileName + ext);
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
assets.push({
name: fileName,
ext,
uuid,
});
}
}
let viewParent = parent.view || viewRoot;
if (!viewParent.hasOwnProperty('children')) {
viewParent.children = [];
}
viewParent.children.push(viewNode);
node.view = viewNode;
});
return {
view: viewRoot,
assets,
}
}
/**
* Created by rockyl on 2019-08-10.
*/
(async function generate() {
const imagesPath = 'zeroing-demo/images_' + Date.now();
const {view, assets} = await execute$1('psd/test.psd', {
imagesPath,
});
console.log(assets);
console.log(view);
})();
//# sourceMappingURL=generator.cjs.js.map
{"version":3,"file":"generator.cjs.js","sources":["../../dist/index.js","generator.js"],"sourcesContent":["import xml from 'xml';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport Color from 'color';\nimport generateUUID from 'uuid/v4';\n\n/**\n * Created by rockyl on 2019-08-09.\n */\n\nconst PSD = require('psd');\n\nasync function getTree(psdFilePath) {\n\tconst psd = await PSD.open(psdFilePath);\n\tconst root = {};\n\twalk(psd.tree(), root);\n\n\treturn root;\n}\n\nfunction walk(psNode, dataNode) {\n\tconst {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};\n\tconst {left, top, width, height, name, layer: {opacity, visible}} = psNode;\n\tconst x = left - pLeft;\n\tconst y = top - pTop;\n\n\tObject.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});\n\tif (psNode.children() && psNode.children().length > 0){\n\t\tdataNode.children = [];\n\t}\n\n\tlet children = psNode.children();\n\tfor (let i = children.length - 1; i >= 0; i--) {\n\t\tconst childPsNode = children[i];\n\n\t\tconst childDataNode = {};\n\t\tdataNode.children.push(childDataNode);\n\t\twalk(childPsNode, childDataNode);\n\t}\n}\n\n/**\n * Created by rockyl on 2019-08-10.\n */\n\nasync function walkNode(node, callback, includeSelf = false) {\n\tif (includeSelf) {\n\t\tawait callback(node, null);\n\t}\n\tif (node.children && node.children.length > 0) {\n\t\tfor (let childNode of node.children) {\n\t\t\tawait callback(childNode, node);\n\t\t\tconst result = await walkNode(childNode, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nasync function walkObject(obj, callback) {\n\tif(typeof obj === \"object\"){\n\t\tfor (let key of Object.keys(obj)) {\n\t\t\tconst value = obj[key];\n\t\t\tawait callback(key, value, obj);\n\t\t\tconst result = await walkObject(value, callback);\n\t\t\tif (result === true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Created by rockyl on 2019-08-10.\n *\n * 导出exml\n */\n\nconst elementTpls = {\n\t'e:Group': [],\n\t'e:Image': {_attr: {source: '{res}'}},\n\t'e:Button': [\n\t\t{_attr: {label: '{1}',}},\n\t\t{\n\t\t\t'e:skinName': [\n\t\t\t\t{\n\t\t\t\t\t'e:Skin': [\n\t\t\t\t\t\t{_attr: {states: 'up,down,disabled'}},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n};\n\nasync function execute(psdFile, options) {\n\tconst {skinFilePath, skinClassName, resPath, resGroupName} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tconst exmlRoot = [\n\t\t{\n\t\t\t_attr: {\n\t\t\t\tclass: skinClassName,\n\t\t\t\twidth: tree.width,\n\t\t\t\theight: tree.height,\n\t\t\t\t'xmlns:e': \"http://ns.egret.com/eui\",\n\t\t\t\t'xmlns:w': \"http://ns.egret.com/wing\",\n\t\t\t},\n\t\t},\n\t];\n\tconst exmlData = {\n\t\t'e:Skin': exmlRoot\n\t};\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible} = node;\n\t\tlet attributes = {width, height, alpha, visible};\n\t\tif (x !== 0) {\n\t\t\tattributes.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tattributes.y = y;\n\t\t}\n\t\tlet element;\n\t\tlet tagName;\n\t\tlet imageResName;\n\t\tlet params;\n\n\t\tlet hasChild = node.hasOwnProperty('children');\n\t\tif (hasChild) {\n\t\t\ttagName = 'e:Group';\n\t\t} else {\n\t\t\tconst nameParams = node.name.split('|');\n\t\t\tconst nodeName = nameParams[0];\n\n\t\t\tattributes.name = nodeName;\n\t\t\timageResName = resGroupName + '_' + nodeName;\n\t\t\tconst imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');\n\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\tif (nameParams.length === 1) {\n\t\t\t\ttagName = 'e:Image';\n\t\t\t} else {\n\t\t\t\tparams = nameParams[1].split(',');\n\t\t\t\ttagName = 'e:' + params[0];\n\t\t\t}\n\n\t\t\t//element[tagName] = {_attr: attributes};\n\t\t}\n\n\t\tlet elementTpl = elementTpls[tagName];\n\t\tlet elementContent;\n\t\tif (elementTpl) {\n\t\t\telementContent = JSON.parse(JSON.stringify(elementTpl));\n\t\t} else {\n\t\t\telementContent = {};\n\t\t}\n\t\telement = {\n\t\t\t[tagName]: elementContent,\n\t\t};\n\n\t\tlet attr;\n\t\tif (Array.isArray(elementContent)) {\n\t\t\tattr = elementContent.find(item => item._attr);\n\t\t\tif (!attr) {\n\t\t\t\tattr = {_attr: {}};\n\t\t\t\telementContent.unshift(attr);\n\t\t\t}\n\t\t} else {\n\t\t\tattr = elementContent;\n\t\t}\n\n\t\tObject.assign(attr._attr, attributes);\n\n\t\tif (imageResName) {\n\t\t\tawait walkObject(element, function (key, value, obj) {\n\t\t\t\tif (value === '{res}') {\n\t\t\t\t\tobj[key] = imageResName;\n\t\t\t\t} else if (typeof value === 'string') {\n\t\t\t\t\tconst result = value.match(/{(\\d+)}/g);\n\t\t\t\t\tif(result){\n\t\t\t\t\t\tfor(let item of result){\n\t\t\t\t\t\t\tconst pi = parseInt(item.match(/{(\\d+)}/)[1]);\n\t\t\t\t\t\t\tvalue = value.replace(item, params[pi]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobj[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (hasChild) {\n\t\t\tnode.exmlNode = elementContent;\n\t\t}\n\n\t\tconst exmlNode = parent.exmlNode || exmlRoot;\n\t\texmlNode.push(element);\n\t});\n\n\tlet exmlStr = xml(exmlData, {declaration: true, indent: true});\n\tawait fs.ensureDir(path.dirname(skinFilePath));\n\tawait fs.writeFile(skinFilePath, exmlStr);\n\n}\n\n/**\n * Created by rockyl on 2019-09-26.\n *\n * 导出zeroing的视图\n */\n\nasync function execute$1(psdFile, options) {\n\tconst {\n\t\timagesPath,\n\t} = options;\n\n\tconst tree = await getTree(psdFile);\n\n\tlet viewRoot = {\n\t\tname: path.basename(psdFile, '.psd'),\n\t\ttype: 'node',\n\t};\n\n\tconst assets = [];\n\n\tawait walkNode(tree, async function (node, parent) {\n\t\tconst {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;\n\t\tlet properties = {\n\t\t\twidth, height, alpha, visible,\n\t\t};\n\t\tlet viewNode = {\n\t\t\tname: node.name,\n\t\t\tproperties,\n\t\t};\n\t\tif (x !== 0) {\n\t\t\tproperties.x = x;\n\t\t}\n\t\tif (y !== 0) {\n\t\t\tproperties.y = y;\n\t\t}\n\n\t\tif(typeTool){\n\t\t\tlet fontInfo= typeTool();\n\t\t\tconst fonts = fontInfo.fonts();\n\t\t\tconst styles = fontInfo.styles();\n\t\t\tconst {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;\n\n\t\t\tproperties.text = fontInfo.textValue;\n\t\t\tproperties.textflow = {\n\t\t\t\tfonts, styles, RunLengthArray,\n\t\t\t};\n\t\t\tviewNode.type = 'label';\n\t\t}else if(solidColor){\n\t\t\tconst {r, g, b} = solidColor();\n\t\t\tlet color = Color({r, g, b});\n\n\t\t\tviewNode.type = 'rect';\n\t\t\tproperties.fillColor = '#' + color.rgbNumber().toString(16);\n\t\t}else{\n\t\t\tif(node.hasOwnProperty('children')){\n\t\t\t\tviewNode.type = 'node';\n\t\t\t}else{\n\t\t\t\tviewNode.type = 'image';\n\n\t\t\t\tconst uuid = generateUUID();\n\t\t\t\tconst fileName = Date.now().valueOf();\n\t\t\t\tconst ext = '.png';\n\n\t\t\t\tproperties.source = 'asset|' + uuid;\n\n\t\t\t\tconst imageFilePath = path.join(imagesPath, fileName + ext);\n\t\t\t\tawait fs.ensureDir(path.dirname(imageFilePath));\n\t\t\t\tawait node.origin.saveAsPng(imageFilePath);\n\n\t\t\t\tassets.push({\n\t\t\t\t\tname: fileName,\n\t\t\t\t\text,\n\t\t\t\t\tuuid,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tlet viewParent = parent.view || viewRoot;\n\t\tif (!viewParent.hasOwnProperty('children')) {\n\t\t\tviewParent.children = [];\n\t\t}\n\t\tviewParent.children.push(viewNode);\n\n\t\tnode.view = viewNode;\n\t});\n\n\treturn {\n\t\tview: viewRoot,\n\t\tassets,\n\t}\n}\n\nexport { getTree, execute as toEgret, execute$1 as toZeroing };\n//# sourceMappingURL=index.js.map\n","/**\n * Created by rockyl on 2019-08-10.\n */\n\nimport {toZeroing} from \"../../dist/index\";\n\n(async function generate() {\n\tconst imagesPath = 'zeroing-demo/images_' + Date.now();\n\n\tconst {view, assets} = await toZeroing('psd/test.psd', {\n\t\timagesPath,\n\t});\n\n\tconsole.log(assets);\n\tconsole.log(view);\n})();\n"],"names":["toZeroing"],"mappings":"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"}
\ No newline at end of file
/**
* Created by rockyl on 2019-08-10.
*/
import {toZeroing} from "../../src/index";
(async function generate() {
const imagesPath = 'zeroing-demo/images_' + Date.now();
const {view, assets} = await toZeroing('psd/test.psd', {
imagesPath,
});
console.log(assets);
console.log(view);
})();
/**
* Created by rockyl on 2019-08-10.
*
* 导出exml
*/
import {getTree} from "./psd-tree";
import {walkNode, walkObject} from "./utils";
import xml from "xml";
import path from "path";
import fs from "fs-extra";
const elementTpls = {
'e:Group': [],
'e:Image': {_attr: {source: '{res}'}},
'e:Button': [
{_attr: {label: '{1}',}},
{
'e:skinName': [
{
'e:Skin': [
{_attr: {states: 'up,down,disabled'}},
{
'e:Image': {_attr: {width: '100%', height: '100%', source: '{res}'}},
},
{
'e:Label': {_attr: {id: 'labelDisplay', horizontalCenter: '0', verticalCenter: '0'}},
}
]
}
]
}
]
};
export async function execute(psdFile, options) {
const {skinFilePath, skinClassName, resPath, resGroupName} = options;
const tree = await getTree(psdFile);
const exmlRoot = [
{
_attr: {
class: skinClassName,
width: tree.width,
height: tree.height,
'xmlns:e': "http://ns.egret.com/eui",
'xmlns:w': "http://ns.egret.com/wing",
},
},
];
const exmlData = {
'e:Skin': exmlRoot
};
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible} = node;
let attributes = {width, height, alpha, visible};
if (x !== 0) {
attributes.x = x;
}
if (y !== 0) {
attributes.y = y;
}
let element;
let tagName;
let imageResName;
let params;
let hasChild = node.hasOwnProperty('children');
if (hasChild) {
tagName = 'e:Group';
} else {
const nameParams = node.name.split('|');
const nodeName = nameParams[0];
attributes.name = nodeName;
imageResName = resGroupName + '_' + nodeName;
const imageFilePath = path.join(resPath, resGroupName + '_p', nodeName + '.png');
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
if (nameParams.length === 1) {
tagName = 'e:Image';
} else {
params = nameParams[1].split(',');
tagName = 'e:' + params[0];
}
//element[tagName] = {_attr: attributes};
}
let elementTpl = elementTpls[tagName];
let elementContent;
if (elementTpl) {
elementContent = JSON.parse(JSON.stringify(elementTpl));
} else {
elementContent = {}
}
element = {
[tagName]: elementContent,
};
let attr;
if (Array.isArray(elementContent)) {
attr = elementContent.find(item => item._attr);
if (!attr) {
attr = {_attr: {}};
elementContent.unshift(attr);
}
} else {
attr = elementContent;
}
Object.assign(attr._attr, attributes);
if (imageResName) {
await walkObject(element, function (key, value, obj) {
if (value === '{res}') {
obj[key] = imageResName;
} else if (typeof value === 'string') {
const result = value.match(/{(\d+)}/g);
if(result){
for(let item of result){
const pi = parseInt(item.match(/{(\d+)}/)[1]);
value = value.replace(item, params[pi])
}
obj[key] = value;
}
}
})
}
if (hasChild) {
node.exmlNode = elementContent;
}
const exmlNode = parent.exmlNode || exmlRoot;
exmlNode.push(element);
});
let exmlStr = xml(exmlData, {declaration: true, indent: true});
await fs.ensureDir(path.dirname(skinFilePath));
await fs.writeFile(skinFilePath, exmlStr);
}
\ No newline at end of file
/**
* Created by rockyl on 2019-08-08.
*/
export {getTree} from "./psd-tree";
export {execute as toEgret} from "./egret";
export {execute as toZeroing} from "./zeroing";
/**
* Created by rockyl on 2019-08-09.
*/
const PSD = require('psd');
export async function getTree(psdFilePath) {
const psd = await PSD.open(psdFilePath);
const root = {};
walk(psd.tree(), root);
return root;
}
function walk(psNode, dataNode) {
const {left: pLeft = 0, top: pTop = 0,} = psNode.parent || {};
const {left, top, width, height, name, layer: {opacity, visible}} = psNode;
const x = left - pLeft;
const y = top - pTop;
Object.assign(dataNode, {x, y, width, height, alpha: opacity / 255, visible, name, origin: psNode, label: `${name} > [${x}, ${y}, ${width}, ${height}]`});
if (psNode.children() && psNode.children().length > 0){
dataNode.children = [];
}
let children = psNode.children();
for (let i = children.length - 1; i >= 0; i--) {
const childPsNode = children[i];
const childDataNode = {};
dataNode.children.push(childDataNode);
walk(childPsNode, childDataNode)
}
}
/**
* Created by rockyl on 2019-08-10.
*/
export async function walkNode(node, callback, includeSelf = false) {
if (includeSelf) {
await callback(node, null);
}
if (node.children && node.children.length > 0) {
for (let childNode of node.children) {
await callback(childNode, node);
const result = await walkNode(childNode, callback);
if (result === true) {
break;
}
}
}
}
export async function walkObject(obj, callback) {
if(typeof obj === "object"){
for (let key of Object.keys(obj)) {
const value = obj[key];
await callback(key, value, obj);
const result = await walkObject(value, callback);
if (result === true) {
break;
}
}
}
}
/**
* Created by rockyl on 2019-09-26.
*
* 导出zeroing的视图
*/
import {getTree} from "./psd-tree";
import {walkNode} from "./utils";
import path from 'path'
import Color from 'color'
import generateUUID from 'uuid/v4'
import fs from "fs-extra";
export async function execute(psdFile, options) {
const {
imagesPath,
} = options;
const tree = await getTree(psdFile);
let viewRoot = {
name: path.basename(psdFile, '.psd'),
type: 'node',
};
const assets = [];
await walkNode(tree, async function (node, parent) {
const {x, y, width, height, alpha, visible, origin: {layer: {typeTool, solidColor}}} = node;
let properties = {
width, height, alpha, visible,
};
let viewNode = {
name: node.name,
properties,
};
if (x !== 0) {
properties.x = x;
}
if (y !== 0) {
properties.y = y;
}
if(typeTool){
let fontInfo= typeTool();
const fonts = fontInfo.fonts();
const styles = fontInfo.styles();
const {RunLengthArray} = fontInfo.engineData.EngineDict.StyleRun;
properties.text = fontInfo.textValue;
properties.textflow = {
fonts, styles, RunLengthArray,
};
viewNode.type = 'label';
}else if(solidColor){
const {r, g, b} = solidColor();
let color = Color({r, g, b});
viewNode.type = 'rect';
properties.fillColor = '#' + color.rgbNumber().toString(16);
}else{
if(node.hasOwnProperty('children')){
viewNode.type = 'node';
}else{
viewNode.type = 'image';
const uuid = generateUUID();
const fileName = Date.now().valueOf();
const ext = '.png';
properties.source = 'asset|' + uuid;
const imageFilePath = path.join(imagesPath, fileName + ext);
await fs.ensureDir(path.dirname(imageFilePath));
await node.origin.saveAsPng(imageFilePath);
assets.push({
name: fileName,
ext,
uuid,
});
}
}
let viewParent = parent.view || viewRoot;
if (!viewParent.hasOwnProperty('children')) {
viewParent.children = [];
}
viewParent.children.push(viewNode);
node.view = viewNode;
});
return {
view: viewRoot,
assets,
}
}
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/code-frame@^7.0.0":
version "7.5.5"
resolved "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
integrity sha1-vAeC9tafe31JUxIZaZuYj2aaj50=
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/highlight@^7.0.0":
version "7.5.0"
resolved "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.5.0.tgz?cache=0&sync_timestamp=1562245140883&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhighlight%2Fdownload%2F%40babel%2Fhighlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540"
integrity sha1-VtETEr2SSPphlZHQJHK+boyzJUA=
dependencies:
chalk "^2.0.0"
esutils "^2.0.2"
js-tokens "^4.0.0"
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=
dependencies:
color-convert "^1.9.0"
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1569560967260&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
"coffee-script@~ 1.7.1":
version "1.7.1"
resolved "https://registry.npm.taobao.org/coffee-script/download/coffee-script-1.7.1.tgz#62996a861780c75e6d5069d13822723b73404bfc"
integrity sha1-YplqhheAx15tUGnROCJyO3NAS/w=
dependencies:
mkdirp "~0.3.5"
"coffeescript-module@~ 0.2.1":
version "0.2.1"
resolved "https://registry.npm.taobao.org/coffeescript-module/download/coffeescript-module-0.2.1.tgz#2c61aa86983cacd226719f9f1dda923cb0ae67b0"
integrity sha1-LGGqhpg8rNImcZ+fHdqSPLCuZ7A=
color-convert@^1.9.0, color-convert@^1.9.1:
version "1.9.3"
resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz?cache=0&sync_timestamp=1566248870121&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolor-convert%2Fdownload%2Fcolor-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=
dependencies:
color-name "1.1.3"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
color-name@^1.0.0:
version "1.1.4"
resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=
color-string@^1.5.2:
version "1.5.3"
resolved "https://registry.npm.taobao.org/color-string/download/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
integrity sha1-ybvF8BtYtUkvPWhXRZy2WQziBMw=
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
color@^3.1.2:
version "3.1.2"
resolved "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10"
integrity sha1-aBSOf4XUGtdknF+oyBBvCY0inhA=
dependencies:
color-convert "^1.9.1"
color-string "^1.5.2"
commander@~2.20.0:
version "2.20.0"
resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.0.tgz?cache=0&sync_timestamp=1569488889962&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha1-1YuytcHuj4ew00ACfp6U4iLFpCI=
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-8.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-extra%2Fdownload%2Ffs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.1"
resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.1.tgz?cache=0&sync_timestamp=1564898698078&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d"
integrity sha1-HB8MNkiCyGj1v/ZRIUYygzahGx0=
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
iconv-lite@^0.4.4, "iconv-lite@~ 0.4.4":
version "0.4.24"
resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=
dependencies:
safer-buffer ">= 2.1.2 < 3"
is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
integrity sha1-RXSirlb3qyBolvtDHq7tBm/fjwM=
jest-worker@^24.0.0:
version "24.9.0"
resolved "https://registry.npm.taobao.org/jest-worker/download/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
integrity sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U=
dependencies:
merge-stream "^2.0.0"
supports-color "^6.1.0"
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha1-GSA/tZmR35jjoocFDUZHzerzJJk=
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
optionalDependencies:
graceful-fs "^4.1.6"
"jspack@~ 0.0.3":
version "0.0.4"
resolved "https://registry.npm.taobao.org/jspack/download/jspack-0.0.4.tgz#32dd35c7fdcb3e3456c18fbb7ef9ed0bc6238177"
integrity sha1-Mt01x/3LPjRWwY+7fvntC8YjgXc=
"lodash@~ 2.4":
version "2.4.2"
resolved "https://registry.npm.taobao.org/lodash/download/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e"
integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=
mkdirp@~0.3.5:
version "0.3.5"
resolved "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7"
integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=
"parse-engine-data@~ 0.1":
version "0.1.2"
resolved "https://registry.npm.taobao.org/parse-engine-data/download/parse-engine-data-0.1.2.tgz#5161f6133c9888f52155ecced42716575dfea052"
integrity sha1-UWH2EzyYiPUhVezO1CcWV13+oFI=
dependencies:
iconv-lite "^0.4.4"
pngjs@3.2.0:
version "3.2.0"
resolved "https://registry.npm.taobao.org/pngjs/download/pngjs-3.2.0.tgz#fc9fcea1a8a375da54a51148019d5abd41dbabde"
integrity sha1-/J/OoaijddpUpRFIAZ1avUHbq94=
psd@^3.2.0:
version "3.2.0"
resolved "https://registry.npm.taobao.org/psd/download/psd-3.2.0.tgz#d721c40207d4c99d82fee4ae2d7cfca4fb073da8"
integrity sha1-1yHEAgfUyZ2C/uSuLXz8pPsHPag=
dependencies:
coffee-script "~ 1.7.1"
coffeescript-module "~ 0.2.1"
iconv-lite "~ 0.4.4"
jspack "~ 0.0.3"
lodash "~ 2.4"
parse-engine-data "~ 0.1"
pngjs "3.2.0"
rsvp "~ 3.0.6"
rollup-plugin-uglify@^6.0.3:
version "6.0.3"
resolved "https://registry.npm.taobao.org/rollup-plugin-uglify/download/rollup-plugin-uglify-6.0.3.tgz#e3f776171344b580bec6c6ab8888622b67099457"
integrity sha1-4/d2FxNEtYC+xsariIhiK2cJlFc=
dependencies:
"@babel/code-frame" "^7.0.0"
jest-worker "^24.0.0"
serialize-javascript "^1.9.0"
uglify-js "^3.4.9"
"rsvp@~ 3.0.6":
version "3.0.21"
resolved "https://registry.npm.taobao.org/rsvp/download/rsvp-3.0.21.tgz#49c588fe18ef293bcd0ab9f4e6756e6ac433359f"
integrity sha1-ScWI/hjvKTvNCrn05nVuasQzNZ8=
"safer-buffer@>= 2.1.2 < 3":
version "2.1.2"
resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=
serialize-javascript@^1.9.0:
version "1.9.1"
resolved "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-1.9.1.tgz?cache=0&sync_timestamp=1567600455468&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb"
integrity sha1-z8IArvd7YAxH2pu4FJyUPnmML9s=
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.npm.taobao.org/simple-swizzle/download/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=
dependencies:
is-arrayish "^0.3.1"
source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM=
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=
dependencies:
has-flag "^3.0.0"
supports-color@^6.1.0:
version "6.1.0"
resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-6.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
integrity sha1-B2Srxpxj1ayELdSGfo0CXogN+PM=
dependencies:
has-flag "^3.0.0"
uglify-js@^3.4.9:
version "3.6.0"
resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
integrity sha1-cEaBNFxTqLIHn7bOwpSwXq0kL/U=
dependencies:
commander "~2.20.0"
source-map "~0.6.1"
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=
uuid@^3.3.3:
version "3.3.3"
resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866"
integrity sha1-RWjwIW54dg7h2/Ok0s9T4iQRKGY=
xml@^1.0.1:
version "1.0.1"
resolved "https://registry.npm.taobao.org/xml/download/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
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