games/FullFire/packages/bitmap-font/panel/index.js

590 lines
27 KiB
JavaScript

let packageName = "bitmap-font";
let fs = require("fire-fs");
let path = require("fire-path");
var Electron = require('electron');
var CfgUtil = Editor.require("packages://bitmap-font/core/CfgUtil");
let charItem = Editor.require('packages://' + packageName + '/panel/item/item.js');
Editor.Panel.extend({
style: fs.readFileSync(Editor.url('packages://' + packageName + '/panel/index.css', 'utf8')) + "",
template: fs.readFileSync(Editor.url('packages://' + packageName + '/panel/index.html', 'utf8')) + "",
$: {
logTextArea: '#logTextArea',
view: '#view',
container: '#container',
section: '#section'
},
ready() {
let logCtrl = this.$logTextArea;
let logListScrollToBottom = function () {
setTimeout(function () {
logCtrl.scrollTop = logCtrl.scrollHeight;
}, 10);
};
let view = this.$view;
let container = this.$container;
let section = this.$section;
let resizeScroll = function () {
if (container && view && container.scrollHeight < view.clientHeight) {
section.style.height = (view.clientHeight - 30) + 'px';
container.style.height = (view.clientHeight - 15) + 'px';
}
};
// 注册自定义组件
charItem.init();
window.addEventListener('resize', function () {
resizeScroll();
});
window.plugin = new window.Vue({
el: this.shadowRoot,
created() {
console.log("created");
// this._initTestData();
this._initPlugin();
resizeScroll();
},
init() {
console.log("init");
},
data: {
uuid: null,
logView: [],
fileSavePath: null,
fileSaveName: null,
fileImportPath: null,
charDataArray: [
/* {
image: 'C:/project/client/cargame/packages/bitmap-font/image/3.png',
imageWidth: 0,
imageHeight: 0,
char: '3',
},
*/
],
cfgArray: ["fsfsfe"],
},
methods: {
onAddCfg() {
this.cfgArray.push("32132423");
},
onCfgSelectChange(event, a, b) {
let value = event.currentTarget.value;
if (value === "添加新配置") {
}
console.log("onCfgSelectChange:" + value);
},
onBtnClickTest() {
console.log("onBtnClickTest");
let indexJS = path.join(Editor.projectInfo.path, "packages/bitmap-font/panel/index.js");
let indexJSMin = path.join(Editor.projectInfo.path, "packages/bitmap-font/panel/index.min.js");
if (!fs.existsSync(indexJS)) {
this._addLog("文件不存在: " + indexJS);
return;
}
let files = fs.readFileSync(indexJS, 'utf-8');
// let JsMin = Editor.require("packages://bitmap-font/node_modules/jsmin");
// let result = JsMin.jsmin(files);
// console.log(result);
// this._addLog(result);
// fs.writeFileSync(indexJSMin, result);
let uglify = Editor.require("packages://bitmap-font/node_modules/uglify-es");
let result = uglify.minify(files);
if (result.error) {
console.log("[%s]:%d-%d %s", result.error.filename, result.error.line, result.error.col, result.error.message);
this._addLog("生成压缩代码失败");
} else {
console.log(result.code);
this._addLog(result.code);
fs.writeFileSync(indexJSMin, result.code);
}
},
_addLog(str) {
let time = new Date();
// this.logView = "[" + time.toLocaleString() + "]: " + str + "\n" + this.logView;
this.logView += "[" + time.toLocaleString() + "]: " + str + "\n";
logListScrollToBottom();
},
delAllCharCfg() {
this.charDataArray.splice(0, this.charDataArray.length);
CfgUtil.saveConfig();
this._addLog('清空配置成功!');
},
delCharCfg(itemCfg) {
if (!itemCfg) {
this._addLog("删除失败");
return;
}
let b = false;
for (let i = 0; i < this.charDataArray.length; i++) {
let item = this.charDataArray[i];
if (item.image === itemCfg.image &&
item.imageWidth === itemCfg.imageWidth &&
item.imageHeight === itemCfg.imageHeight) {
this.charDataArray.splice(i, 1);
this._addLog("del: " + item.image);
b = true;
}
}
if (b) {
CfgUtil.saveConfig();
}
},
_initTestData() {
this._addImage('C:/project/client/cargame/packages/bitmap-font/image/3.png', '3');
this._addImage('C:/project/client/cargame/packages/bitmap-font/image/0.png', '0');
},
_initPlugin() {
CfgUtil.initCfg(function (data) {
// 默认一个bitmap临时存放目录
this._initTmpDir();
if (data) {
this.fileSaveName = data.saveName;
this.fileImportPath = data.saveImport;
this.charDataArray = data.bitMapCfg || [];
this.charDataArray.sort(function (a, b) {
let pathA = a.image;
let pathB = b.image;
let extA = path.basename(pathA);
let extB = path.basename(pathB);
let numA = extA.charCodeAt(0);
let numB = extB.charCodeAt(0);
return numA - numB;
});
}
}.bind(this));
},
_initTmpDir() {
let userPath = Electron.remote.app.getPath('userData');
let tempDir = path.join(userPath, "/bitmap-font");// 临时目录
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir);
}
this.fileSavePath = tempDir;
},
// todo 测试窗口改变的时候,改变div尺寸
onWinResize() {
this.$nextTick(function () {
let arr = this.$el.ownerDocument.getElementsByClassName('fit');
let bitmap = arr.namedItem('bitmap-font');
if (bitmap) {
bitmap.onresize = function () {
console.log('on win resize');
}
}
});
},
onClickOpen() {
if (this.fileSavePath) {
Electron.shell.showItemInFolder(this.fileSavePath);
Electron.shell.beep();
}
},
onClickSelect() {
let res = Editor.Dialog.openFile({
title: "选择保存目录",
defaultPath: Editor.projectInfo.path,
properties: ['openDirectory'],
});
if (res !== -1) {
let dir = res[0];
this.fileSavePath = dir;
CfgUtil.setSavePath(dir);
}
},
onUpdateSaveName(event) {
if (this.fileSaveName) {
let reg = new RegExp('^[^\\\\\\/:*?\\"<>|]+$');
if (reg.test(this.fileSaveName)) {
if (this.fileSaveName.indexOf('.') !== -1) {
let arr = this.fileSaveName.split('.');
this._addLog(this.fileSaveName + "不需要包含扩展名,已经自动修改为:" + arr[0]);
this.fileSaveName = arr[0];
}
CfgUtil.setSaveName(this.fileSaveName);
} else {
this._addLog("文件名不符合规则:" + this.fileSaveName);
this.fileSaveName = "";
}
} else if (this.fileSaveName.length === 0) {
this._addLog("保存文件名不能为空");
}
},
// 选择导入的地方
onSelectImportPath() {
let res = Editor.Dialog.openFile({
title: "选择导出目录",
defaultPath: Editor.projectInfo.path,
properties: ['openDirectory'],
});
if (res !== -1) {
let dir = res[0];
let dir2 = Editor.assetdb.remote.fspathToUrl(dir);
// let b = Editor.assetdb.remote.isSubAssetByPath(dir2);
if (dir2.indexOf("db://") === -1) {
this._addLog("不是项目资源目录:" + dir);
this.fileImportPath = "";
} else {
this.fileImportPath = dir2;
CfgUtil.setSaveImport(dir2);
}
}
},
onGenAndImportFont() {
// 逆向索引出文件名
Editor.assetdb.queryInfoByUuid(this.uuid, function (err, info) {
if (err) {
this._addLog(err);
} else {
let fontPath = info.path;
let fontDir = path.dirname(fontPath);
let fontName = path.basename(fontPath, '.fnt');
this.onGen(fontName, function () {
this._addLog("导入bitmap-font到项目!");
let url = Editor.assetdb.remote.fspathToUrl(fontDir);
setTimeout(function () {
this.onImport(fontName, url);
}.bind(this), 500);
}.bind(this));
}
}.bind(this));
},
onImportFont() {
this.onImport(this.fileSaveName, this.fileImportPath);
},
onImport(fileSaveName, fileImportPath) {
if (!fileImportPath) {
this._addLog("导出目录错误:" + fileImportPath);
return;
}
let fontPng = path.join(this.fileSavePath, fileSaveName + ".png");
if (!fs.existsSync(fontPng)) {
this._addLog("fnt图片文件不存在:" + fontPng);
return;
}
let fontFile = path.join(this.fileSavePath, fileSaveName + ".fnt");
if (!fs.existsSync(fontFile)) {
this._addLog("fnt字体文件不存在:" + fontFile);
return;
}
let pngUrl = fileImportPath + "/" + fileSaveName + ".png";
let fontUrl = fileImportPath + "/" + fileSaveName + ".fnt";
// Editor.assetdb.delete([pngUrl, fontUrl]);
Editor.assetdb.import([fontPng, fontFile], fileImportPath, true,
function (err, results) {
this._addLog("导入成功!");
Editor.assetdb.refresh(fileImportPath);
results.forEach(function (result, cur, total) {
// console.log(result.path);
// result.uuid
// result.parentUuid
// result.url
// result.path
// result.type
});
}.bind(this));
},
onGen(fileSaveName, callBack) {
if (this.fileSavePath && fs.existsSync(this.fileSavePath)) {
} else {
this._addLog("文件保存目录不存在: " + this.fileSavePath);
return;
}
let unSetChar = this._checkAllCharValueIsSet();
if (unSetChar) {
this._addLog("该图片没有设置字符: " + unSetChar.image);
return;
}
if (this.charDataArray.length <= 0) {
this._addLog("请导入图片!");
return;
}
let sprites = [];
for (let i = 0; i < this.charDataArray.length; i++) {
sprites.push(this.charDataArray[i].image);
}
this._addLog("生成中...");
let SpriteSmith = Editor.require("packages://bitmap-font/node_modules/spritesmith");
SpriteSmith.run(
{src: sprites, algorithm: 'left-right'},
function (err, result) {
if (err) {
console.log(err);
} else {
let outPutFilePath = path.join(this.fileSavePath, fileSaveName + ".png");
fs.writeFileSync(outPutFilePath, result.image);
// 得到配置之后生成font字体
/*
* info face="微软雅黑" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="2_0.png"
chars count=3
char id=49 x=19 y=0 width=14 height=23 xoffset=0 yoffset=0 xadvance=14 page=0 chnl=15
char id=50 x=0 y=0 width=18 height=23 xoffset=0 yoffset=0 xadvance=18 page=0 chnl=15
char id=51 x=34 y=0 width=19 height=20 xoffset=0 yoffset=0 xadvance=19 page=0 chnl=15
* */
let util = require('util');
let infoCfg = "info face=\"微软雅黑\" size=40 bold=0 italic=0 charset=\"\" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0\n";
let commonCfg = util.format("common lineHeight=40 base=26 scaleW=%d scaleH=%d pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0\n",
result.properties.width, result.properties.height);
let pageCfg = util.format("page id=0 file=\"%s.png\"\n", fileSaveName);
// 字符数量配置
let charsCfg = util.format("chars count=%d\n", this.charDataArray.length);
let charArrCfg = "";
// 字符串配置
for (let k in result.coordinates) {
let itemCharCfg = this._setCharData(k, result.coordinates[k]);
if (itemCharCfg) {
charArrCfg += itemCharCfg;
} else {
this._addLog("该图片没有设置字符: " + k);
this._addLog("生成font字体失败!");
return;
}
}
let cfg = infoCfg + commonCfg + pageCfg + charsCfg + charArrCfg;
// console.log("生成的配置:\n" + cfg);
let savePath = path.join(this.fileSavePath, fileSaveName + ".fnt");
fs.writeFileSync(savePath, cfg);
this._addLog("生成成功, 文件保存在:" + savePath);
if (callBack) {
callBack();
}
}
}.bind(this));
},
onClickGen() {
this.onGen(this.fileSaveName);
/*
// 高度要一致,宽度可以不用一致
let imgFileLen = this.charDataArray.length;
if (imgFileLen > 1) {
let sharp = require(Editor.url('unpack://utils/sharp'));
// 检索出总宽度和高度
let pngWidth = 0;
let pngHeight = this.charDataArray[0].imageHeight;
for (let i = 0; i < imgFileLen; i++) {
let item = this.charDataArray[i];
pngWidth += item.imageWidth;
if (item.imageHeight > pngHeight) {
pngHeight = item.imageHeight;
}
}
let canvas = document.createElement('canvas');
canvas.width = pngWidth;
canvas.height = pngHeight;
let ctx = canvas.getContext('2d');
ctx.rect(0,0,pngWidth,pngHeight);
ctx.fillStyle='transparent';
ctx.fill();
let drawX = 0;
function drawing(index) {
if (index < this.charDataArray.length) {
let itemData = this.charDataArray[index];
let drawImg = new Image();
drawImg.src = itemData.image;
drawImg.onload = function () {
ctx.drawImage(drawImg, drawX, 0, itemData.imageWidth, itemData.imageHeight);
drawing(index + 1);
};
} else {
}
}
drawing(0);
return;
// 先创建好需要大小的尺寸图片
let image1 = this.charDataArray[0].image;
let buffer = Buffer.alloc(pngWidth * pngHeight * 4, 0);
let img = sharp(buffer, {
create: {
width: pngWidth,
height: pngHeight,
channels: 4,
background: {r: 0, g: 0, b: 0, alpha: 0}
}
});
img.background({r: 0, g: 0, b: 0, alpha: 0});
// .extract({left: 0, top: 0, width: 10, height:10})
img.extend({top: 0, left: 0, bottom: pngHeight, right: pngWidth});
// 将所有图片扩展到height的尺寸
// 混合图片
for (let i = 1; i < imgFileLen; i++) {
let itemFileData = this.charDataArray[i];
img.overlayWith(itemFileData.image, {left: itemFileData.imageWidth, top: 0});
}
// 输出保存
let filePath = path.join(this.fileSavePath, "/out.png");
img.toFile(filePath, function (err, info) {
if (err) {
console.log("error :" + err);
} else {
console.log("生成成功!");
}
});
}
*/
},
// 检查字符是否设置
_checkAllCharValueIsSet() {
for (let i = 0; i < this.charDataArray.length; i++) {
let item = this.charDataArray[i];
if (item.char === null) {
return item;
} else if (item.char === "") {
return item;
}
}
return null;
},
checkIsContentRepeatChar(char) {
let repeatChar = [];
for (let i = 0; i < this.charDataArray.length; i++) {
let item = this.charDataArray[i];
if (item.char === char) {
repeatChar.push(item);
}
}
if (repeatChar.length > 1) {
let util = require('util');
let str = util.format("发现多张图片对应同一个字符[%s] :\n", char);
for (let j = 0; j < repeatChar.length; j++) {
str += repeatChar[j].image + "\n";
}
this._addLog(str);
return true;
} else {
return false;
}
},
_setCharData(png, coordinateData) {
let util = require('util');
let char = null;
for (let i = 0; i < this.charDataArray.length; i++) {
let item = this.charDataArray[i];
if (item.image === png) {
char = item.char;
break;
}
}
if (char && char.length === 1) {
let charId = char.charCodeAt(0);
let charStr = util.format("char id=%d x=%d y=%d width=%d height=%d xoffset=0 yoffset=0 xadvance=%d page=0 chnl=15\n",
charId, coordinateData.x, coordinateData.y, coordinateData.width, coordinateData.height, coordinateData.width);
return charStr;
} else {
this._addLog("没有发现字符");
return null;
}
},
drop(event) {
event.preventDefault();
console.log("drop");
for (let i = 0; i < event.dataTransfer.files.length; i++) {
let file = event.dataTransfer.files[i];
let filePath = file.path;
if (file.type === "image/png") {
// 判断是否有重复的图片
if (this._isSameFileExist(filePath)) {
this._addLog("已经存在该图片: " + filePath);
} else {
this._addImage(filePath, null);
}
} else {
this._addLog("只能识别图片: " + filePath);
}
}
CfgUtil.saveConfig();
return false;
},
_addImage(filePath, char) {
let imageSize = require(Editor.url("packages://bitmap-font/node_modules/image-size"));
let size = imageSize(filePath);
let item = {
image: filePath,
char: char,
imageWidth: size.width,
imageHeight: size.height
};
this.charDataArray.push(item);
// 排序,按照字母数字排序
this.charDataArray.sort(function (a, b) {
let pathA = a.image;
let pathB = b.image;
let extA = path.basename(pathA);
let extB = path.basename(pathB);
let numA = extA.charCodeAt(0);
let numB = extB.charCodeAt(0);
return numA - numB;
});
CfgUtil.setBitmapCfg(this.charDataArray);
},
_isSameFileExist(file) {
let b = false;
for (let i = 0; i < this.charDataArray.length; i++) {
if (this.charDataArray[i].image === file) {
b = true;
break;
}
}
return b;
},
dragOver(event) {
// 只有这个控制是否有效
event.preventDefault();
event.stopPropagation();
// console.log("dragOver");
},
dragEnter(event) {
event.preventDefault();
event.stopPropagation();
// console.log("dragEnter");
},
dragLeave(event) {
event.preventDefault();
// console.log("dragLeave");
},
}
});
},
// register your ipc messages here
messages: {
'bitmap-font:onClickDelChar'(event, data) {
window.plugin.delCharCfg(data);
},
'bitmap-font:onClickDelAllChar'(event, data) {
window.plugin.delAllCharCfg(data);
},
}
});