index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. const Fs = require('fs');
  2. const { dialog } = require('electron').remote;
  3. Editor.Panel.extend({
  4. style: Fs.readFileSync(Editor.url('packages://bitmapfont/panel/index.css', 'utf8')),
  5. template: Fs.readFileSync(Editor.url('packages://bitmapfont/panel/index.html', 'utf8')),
  6. $: {
  7. fontCanvas: "#fontCanvas"
  8. },
  9. ready() {
  10. let self = this;
  11. this.plugin = new window.Vue({
  12. el: this.shadowRoot,
  13. data() {
  14. return {
  15. filePath: "",
  16. imageList: [],
  17. updateImageList: [],
  18. canvasWidth: 256,
  19. canvasHeight: 256,
  20. fontInfo: '',
  21. }
  22. },
  23. methods: {
  24. dragEnter(e) {
  25. e.stopPropagation();
  26. e.preventDefault();
  27. },
  28. dragOver(e) {
  29. e.stopPropagation();
  30. e.preventDefault();
  31. },
  32. onDrop(e) {
  33. this.removeAll();
  34. this.canvasWidth = 256;
  35. this.canvasHeight = 256;
  36. e.stopPropagation();
  37. e.preventDefault();
  38. let dt = e.dataTransfer;
  39. let files = dt.files;
  40. this.showImgData(files);
  41. },
  42. showImgData(files) {
  43. let that = this;
  44. if (files.length) {
  45. let successCount = 0;
  46. for (var i = 0; i < files.length; i++) {
  47. let file = files[i];
  48. if (!/^image\//.test(file.type)) continue;
  49. let fileReader = new FileReader();
  50. fileReader.onload = (function() {
  51. return function(e) {
  52. if (that.updateImageList.indexOf(e.target.result) !== -1) return;
  53. var img = new Image();
  54. img.src = e.target.result;
  55. img.onload = () => {
  56. let fileName = file.name.split('.')[0];
  57. that.imageList.push({
  58. img: e.target.result,
  59. char: fileName.substr(fileName.length - 1, 1),
  60. width: img.width,
  61. height: img.height,
  62. x: 0,
  63. y: 0,
  64. });
  65. that.updateImageList.push(e.target.result);
  66. that.updateCanvas(null, (maxX, maxY) => {
  67. successCount++;
  68. if (successCount >= files.length) {
  69. that.canvasWidth = maxX + 2;
  70. that.canvasHeight = maxY;
  71. setTimeout(() => {
  72. that.updateCanvas(null)
  73. }, 10)
  74. }
  75. });
  76. };
  77. };
  78. })();
  79. fileReader.readAsDataURL(file);
  80. }
  81. }
  82. },
  83. updateCanvas(data, func) {
  84. if (!this.imageList.length) return;
  85. let that = this;
  86. let height = 0;
  87. let space = 2;
  88. let x = space;
  89. let y = space;
  90. let maxX = x;
  91. let maxY = y;
  92. this.imageList.forEach(img => {
  93. if (img.height > height) height = img.height;
  94. });
  95. height = Math.ceil(height);
  96. this.fontSize = height;
  97. let content = self.$fontCanvas.getContext('2d');
  98. content.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
  99. this.imageList.forEach(img2 => {
  100. let img = new Image();
  101. img.src = img2.img;
  102. if (x + img2.width + space > that.canvasWidth) {
  103. y += height + space;
  104. if (y + height + space > that.canvasHeight) {
  105. that.canvasWidth += (x + img2.width + space);
  106. that.canvasHeight += y;
  107. }
  108. x = space;
  109. }
  110. content.drawImage(img, x, y);
  111. img2.x = x;
  112. img2.y = y;
  113. x += img2.width + space;
  114. if (maxX < x) {
  115. maxX = x;
  116. }
  117. if (maxY < y + height + space) {
  118. maxY = y + height + space;
  119. }
  120. });
  121. func && func(maxX, maxY);
  122. },
  123. loadFileData() {
  124. let str = `info size=${this.fontSize} unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
  125. common lineHeight=${this.fontSize} base=23 scaleW=${this.canvasWidth} scaleH=${this.canvasHeight} pages=1 packed=0
  126. page id=0 file="${this.fontName}.png"
  127. chars count=${this.imageList.length}`;
  128. this.imageList.forEach(img => {
  129. str += `char id=${this.caseConvertEasy(img.char).charCodeAt(0)} x=${img.x} y=${img.y} width=${img.width} height=${img.height} xoffset=0 yoffset=0 xadvance=${img.width} \n`;
  130. })
  131. this.fontInfo = str;
  132. },
  133. caseConvertEasy(str) {
  134. return str.split('').map(s => {
  135. if (s.charCodeAt() <= 90) {
  136. return s.toUpperCase()
  137. }
  138. return s.toLowerCase()
  139. }).join('')
  140. },
  141. removeAll() {
  142. this.imageList = [];
  143. this.updateImageList = [];
  144. this.updateCanvas();
  145. },
  146. save() {
  147. this.selectFolder(() => {
  148. this.loadFileData();
  149. this.savePng();
  150. this.saveFnt();
  151. })
  152. },
  153. selectFolder(func) {
  154. let self = this;
  155. Editor.Scene.callSceneScript('bitmapfont', 'getCocosVersion', function(err, version) {
  156. let result = self.compareVersion(version, "2.4.5");
  157. Editor.log("版本号: ", version, "结果", result);
  158. if (result >= 0) { //大于等于2.4.5版本
  159. dialog.showSaveDialog({ properties: ['openDirectory'] }).then(result => {
  160. let fontPath = result.filePath;
  161. Editor.log("保存路径: ", fontPath);
  162. self.selectSuccess(fontPath, func);
  163. }).catch(err => {
  164. Editor.log(err)
  165. })
  166. } else { //
  167. let fontPath = dialog.showSaveDialog({ properties: ['openDirectory', ] });
  168. Editor.log("保存路径: ", fontPath);
  169. self.selectSuccess(fontPath, func);
  170. }
  171. });
  172. },
  173. compareVersion(v1, v2) {
  174. let vers1 = v1.split('.');
  175. let vers2 = v2.split('.');
  176. const len = Math.max(v1.length, v2.length)
  177. while (vers1.length < len) {
  178. vers1.push('0')
  179. }
  180. while (vers2.length < len) {
  181. vers2.push('0')
  182. }
  183. for (let i = 0; i < len; i++) {
  184. const num1 = parseInt(vers1[i])
  185. const num2 = parseInt(vers2[i])
  186. if (num1 > num2) {
  187. return 1
  188. } else if (num1 < num2) {
  189. return -1
  190. }
  191. }
  192. return 0
  193. },
  194. selectSuccess(fontPath, func) {
  195. if (fontPath) {
  196. var agent = navigator.userAgent.toLowerCase();
  197. let fontArr = [];
  198. var isMac = /macintosh|mac os x/i.test(navigator.userAgent);
  199. /**32或者64位 windoiws系统 */
  200. let isWindows = (agent.indexOf("win32") >= 0 || agent.indexOf("wow32") >= 0) || (agent.indexOf("win64") >= 0 || agent.indexOf("wow64") >= 0)
  201. if (isWindows) {
  202. fontArr = fontPath.split("\\");
  203. }
  204. if (isMac) {
  205. fontArr = fontPath.split("/");
  206. }
  207. this.fontName = fontArr[fontArr.length - 1];
  208. this.filePath = fontPath.replace("\\" + this.fontName, "");
  209. if (this.filePath) {
  210. Editor.log("选择完成,保存中");
  211. func();
  212. }
  213. }
  214. },
  215. saveFnt() {
  216. Fs.writeFileSync(this.filePath.replace(/\\/g, "/") + '/' + this.fontName + '.fnt', this.fontInfo);
  217. },
  218. savePng() {
  219. let src = self.$fontCanvas.toDataURL("image/png");
  220. let data = src.replace(/^data:image\/\w+;base64,/, "");
  221. let buffer = new window.Buffer(data, 'base64');
  222. Fs.writeFileSync(this.filePath.replace(/\\/g, "/") + '/' + this.fontName + '.png', buffer);
  223. Editor.log("保存成功");
  224. }
  225. }
  226. })
  227. },
  228. });