QS-SharePoster.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. /* eslint-disable */
  2. import _app from './app.js';
  3. import QRCodeAlg from './QRCodeAlg.js';
  4. const ShreUserPosterBackgroundKey = 'ShrePosterBackground_'; // 背景图片缓存名称前缀
  5. const idKey = 'QSSHAREPOSTER_IDKEY'; //drawArray自动生成的idkey
  6. var isMp = false;
  7. // #ifdef MP
  8. isMp = true;
  9. // #endif
  10. var nbgScale = 1;
  11. // export default
  12. function getSharePoster(obj) {
  13. return new Promise(async (resolve, reject) => {
  14. try {
  15. const result1 = await returnPromise(obj);
  16. resolve(result1);
  17. } catch (e) {
  18. //TODO handle the exception
  19. try {
  20. if(obj.bgScale) {
  21. obj.bgScale = Number(obj.bgScale) - 0.1
  22. }else{
  23. nbgScale = nbgScale - 0.1
  24. }
  25. _app.log('------------清除缓存后, 开始第二次尝试------------');
  26. const result2 = await returnPromise(obj);
  27. resolve(result2);
  28. } catch (e) {
  29. //TODO handle the exception
  30. reject(e);
  31. }
  32. }
  33. })
  34. }
  35. function returnPromise(obj) {
  36. let {
  37. type,
  38. formData,
  39. background,
  40. posterCanvasId,
  41. backgroundImage,
  42. reserve,
  43. textArray,
  44. drawArray,
  45. qrCodeArray,
  46. imagesArray,
  47. setCanvasWH,
  48. setCanvasToTempFilePath,
  49. setDraw,
  50. bgScale,
  51. Context,
  52. _this,
  53. delayTimeScale,
  54. drawDelayTime
  55. } = obj;
  56. return new Promise(async (rs, rj) => {
  57. try {
  58. _app.showLoading('正在准备海报数据');
  59. if (!Context) {
  60. _app.log('没有画布对象,创建画布对象');
  61. Context = uni.createCanvasContext(posterCanvasId, (_this || null));
  62. }
  63. let bgObj;
  64. if (background && background.width && background.height) {
  65. bgObj = background;
  66. } else {
  67. bgObj = await getShreUserPosterBackground({
  68. backgroundImage,
  69. type,
  70. formData
  71. });
  72. }
  73. bgScale = bgScale || nbgScale;
  74. bgObj.width = bgObj.width * bgScale;
  75. bgObj.height = bgObj.height * bgScale;
  76. _app.log('获取背景图信息对象成功:' + JSON.stringify(bgObj));
  77. const params = {
  78. bgObj,
  79. type,
  80. bgScale
  81. };
  82. if (setCanvasWH && typeof(setCanvasWH) == 'function') {
  83. await new Promise((resolve, reject)=>{
  84. setCanvasWH(params);
  85. setTimeout(()=>{
  86. resolve();
  87. }, 0)
  88. })
  89. }
  90. if (imagesArray) {
  91. if (typeof(imagesArray) == 'function')
  92. imagesArray = imagesArray(params);
  93. _app.showLoading('正在生成需绘制图片的临时路径');
  94. _app.log('准备设置图片');
  95. imagesArray = await setImage(imagesArray);
  96. _app.hideLoading();
  97. }
  98. if (textArray) {
  99. if (typeof(textArray) == 'function')
  100. textArray = textArray(params);
  101. textArray = setText(Context, textArray);
  102. }
  103. if (qrCodeArray) {
  104. if (typeof(qrCodeArray) == 'function')
  105. qrCodeArray = qrCodeArray(params);
  106. _app.showLoading('正在生成需绘制图片的临时路径');
  107. for (let i = 0; i < qrCodeArray.length; i++) {
  108. _app.log(i);
  109. if (qrCodeArray[i].image)
  110. qrCodeArray[i].image = await _app.downloadFile_PromiseFc(qrCodeArray[i].image);
  111. }
  112. _app.hideLoading();
  113. }
  114. if (drawArray) {
  115. if (typeof(drawArray) == 'function') {
  116. drawArray = drawArray(params);
  117. }
  118. if (_app.isPromise(drawArray)) {
  119. drawArray = await drawArray;
  120. }
  121. if (_app.isArray(drawArray) && drawArray.length > 0) {
  122. let hasAllInfoCallback = false;
  123. for (let i = 0; i < drawArray.length; i++) {
  124. const drawArrayItem = drawArray[i];
  125. if (_app.isFn(drawArrayItem.allInfoCallback) && !hasAllInfoCallback) hasAllInfoCallback = true;
  126. drawArrayItem[idKey] = i;
  127. let newData;
  128. switch (drawArrayItem.type) {
  129. case 'image':
  130. newData = await setImage(drawArrayItem);
  131. break;
  132. case 'text':
  133. newData = setText(Context, drawArrayItem);
  134. break;
  135. case 'qrcode':
  136. if (drawArrayItem.image)
  137. newData = {
  138. image: await _app.downloadFile_PromiseFc(drawArrayItem.image)
  139. };
  140. break;
  141. case 'custom':
  142. break;
  143. default:
  144. _app.log('未识别的类型');
  145. break;
  146. }
  147. if (newData && _app.isObject(newData)) {
  148. drawArray[i] = { ...drawArrayItem,
  149. ...newData
  150. }
  151. };
  152. }
  153. if (hasAllInfoCallback) {
  154. _app.log('----------------hasAllInfoCallback----------------');
  155. const drawArray_copy = [...drawArray];
  156. drawArray_copy.sort((a, b) => {
  157. const a_serialNum = !_app.isUndef(a.serialNum) && !_app.isNull(a.serialNum) ? Number(a.serialNum) : Number.NEGATIVE_INFINITY;
  158. const b_serialNum = !_app.isUndef(b.serialNum) && !_app.isNull(b.serialNum) ? Number(b.serialNum) : Number.NEGATIVE_INFINITY;
  159. return a_serialNum - b_serialNum;
  160. })
  161. _app.log('开始for循环');
  162. for (let i = 0; i < drawArray_copy.length; i++) {
  163. const item = { ...drawArray_copy[i]
  164. };
  165. if (_app.isFn(item.allInfoCallback)) {
  166. let newData = item.allInfoCallback({
  167. drawArray
  168. });
  169. if (_app.isPromise(newData)) newData = await newData;
  170. const item_idKey = item[idKey];
  171. if (!_app.isUndef(item_idKey)) {
  172. drawArray[item[idKey]] = { ...item,
  173. ...newData
  174. };
  175. } else {
  176. console.log('程序错误 找不到idKey!!! ...这不应该啊');
  177. }
  178. }
  179. }
  180. _app.log('for循环结束');
  181. }
  182. }
  183. }
  184. const poster = await drawShareImage({
  185. Context,
  186. type,
  187. posterCanvasId,
  188. reserve,
  189. drawArray,
  190. textArray,
  191. imagesArray,
  192. bgObj,
  193. qrCodeArray,
  194. setCanvasToTempFilePath,
  195. setDraw,
  196. bgScale,
  197. _this,
  198. delayTimeScale,
  199. drawDelayTime
  200. });
  201. _app.hideLoading();
  202. rs({
  203. bgObj,
  204. poster,
  205. type
  206. });
  207. } catch (e) {
  208. //TODO handle the exception
  209. rj(e);
  210. }
  211. });
  212. }
  213. function drawShareImage(obj) { //绘制海报方法
  214. let {
  215. Context,
  216. type,
  217. posterCanvasId,
  218. reserve,
  219. bgObj,
  220. drawArray,
  221. textArray,
  222. qrCodeArray,
  223. imagesArray,
  224. setCanvasToTempFilePath,
  225. setDraw,
  226. bgScale,
  227. _this,
  228. delayTimeScale,
  229. drawDelayTime
  230. } = obj;
  231. const params = {
  232. Context,
  233. bgObj,
  234. type,
  235. bgScale
  236. };
  237. delayTimeScale = delayTimeScale !== undefined ? delayTimeScale : 15;
  238. drawDelayTime = drawDelayTime !== undefined ? drawDelayTime : 100;
  239. return new Promise((rs, rj) => {
  240. try {
  241. _app.showLoading('正在绘制海报');
  242. _app.log('背景对象:' + JSON.stringify(bgObj));
  243. if (bgObj && bgObj.path) {
  244. _app.log('背景有图片路径');
  245. Context.drawImage(bgObj.path, 0, 0, bgObj.width, bgObj.height);
  246. } else {
  247. _app.log('背景没有图片路径');
  248. if (bgObj.backgroundColor) {
  249. _app.log('背景有背景颜色:' + bgObj.backgroundColor);
  250. Context.setFillStyle(bgObj.backgroundColor);
  251. Context.fillRect(0, 0, bgObj.width, bgObj.height);
  252. } else {
  253. _app.log('背景没有背景颜色');
  254. }
  255. }
  256. _app.showLoading('绘制图片');
  257. if (imagesArray && imagesArray.length > 0)
  258. drawImage(Context, imagesArray);
  259. _app.showLoading('绘制自定义内容');
  260. if (setDraw && typeof(setDraw) == 'function') setDraw(params);
  261. _app.showLoading('绘制文本');
  262. if (textArray && textArray.length > 0)
  263. drawText(Context, textArray, bgObj);
  264. _app.showLoading('绘制二维码');
  265. if (qrCodeArray && qrCodeArray.length > 0) {
  266. for (let i = 0; i < qrCodeArray.length; i++) {
  267. drawQrCode(Context, qrCodeArray[i]);
  268. }
  269. }
  270. _app.showLoading('绘制可控层级序列');
  271. if (drawArray && drawArray.length > 0) {
  272. for (let i = 0; i < drawArray.length; i++) {
  273. const drawArrayItem = drawArray[i];
  274. _app.log('绘制可控层级序列, drawArrayItem:' + JSON.stringify(drawArrayItem));
  275. switch (drawArrayItem.type) {
  276. case 'image':
  277. _app.log('绘制可控层级序列, 绘制图片');
  278. drawImage(Context, drawArrayItem);
  279. break;
  280. case 'text':
  281. _app.log('绘制可控层级序列, 绘制文本');
  282. drawText(Context, drawArrayItem, bgObj);
  283. break;
  284. case 'qrcode':
  285. _app.log('绘制可控层级序列, 绘制二维码');
  286. drawQrCode(Context, drawArrayItem);
  287. break;
  288. case 'custom':
  289. _app.log('绘制可控层级序列, 绘制自定义内容');
  290. if (drawArrayItem.setDraw && typeof drawArrayItem.setDraw === 'function')
  291. drawArrayItem.setDraw(Context);
  292. break;
  293. default:
  294. _app.log('未识别的类型');
  295. break;
  296. }
  297. }
  298. }
  299. _app.showLoading('绘制中')
  300. setTimeout(() => {
  301. _app.log('准备执行draw方法')
  302. _app.log('Context:' + Context);
  303. const fn = function(){
  304. _app.showLoading('正在绘制海报');
  305. let setObj = setCanvasToTempFilePath || {};
  306. if (setObj && typeof(setObj) == 'function')
  307. setObj = setCanvasToTempFilePath(bgObj, type);
  308. let canvasToTempFilePathFn;
  309. // #ifdef H5
  310. canvasToTempFilePathFn = function() {
  311. _app.hideLoading();
  312. rs({
  313. tempFilePath: document.querySelector(`uni-canvas[canvas-id=${posterCanvasId}]>canvas`).toDataURL(
  314. `image/${setObj.fileType||'jpg'}`, setObj.quality || .8)
  315. });
  316. }
  317. // #endif
  318. // #ifndef H5
  319. const data = {
  320. x: 0,
  321. y: 0,
  322. width: bgObj.width,
  323. height: bgObj.height,
  324. destWidth: bgObj.width * 2, // 若H5使用这里请不要乘以二
  325. destHeight: bgObj.height * 2, // 若H5使用这里请不要乘以二
  326. quality: .8,
  327. fileType: 'jpg',
  328. ...setObj
  329. };
  330. _app.log('canvasToTempFilePath的data对象:' + JSON.stringify(data));
  331. canvasToTempFilePathFn = function() {
  332. const toTempFilePathObj = { //输出为图片
  333. ...data,
  334. canvasId: posterCanvasId,
  335. success(res) {
  336. _app.hideLoading();
  337. rs(res);
  338. },
  339. fail(err) {
  340. _app.hideLoading();
  341. _app.log('输出图片失败:' + JSON.stringify(err));
  342. rj('输出图片失败:' + JSON.stringify(err))
  343. }
  344. }
  345. uni.canvasToTempFilePath(toTempFilePathObj, _this || null);
  346. }
  347. // #endif
  348. let delayTime = 0;
  349. if (qrCodeArray) {
  350. qrCodeArray.forEach(item => {
  351. if (item.text) {
  352. delayTime += Number(item.text.length);
  353. }
  354. })
  355. }
  356. if (imagesArray) {
  357. imagesArray.forEach(() => {
  358. delayTime += delayTimeScale;
  359. })
  360. }
  361. if (textArray) {
  362. textArray.forEach(() => {
  363. delayTime += delayTimeScale;
  364. })
  365. }
  366. if (drawArray) {
  367. drawArray.forEach(item => {
  368. switch (item.type) {
  369. case 'text':
  370. if (item.text) {
  371. delayTime += item.text.length;
  372. }
  373. break;
  374. default:
  375. delayTime += delayTimeScale;
  376. break;
  377. }
  378. })
  379. }
  380. _app.log('延时系数:' + delayTimeScale);
  381. _app.log('总计延时:' + delayTime);
  382. setTimeout(canvasToTempFilePathFn, delayTime);
  383. }
  384. Context.draw((typeof(reserve) == 'boolean' ? reserve : false), fn);
  385. }, drawDelayTime);
  386. } catch (e) {
  387. //TODO handle the exception
  388. _app.hideLoading();
  389. rj(e);
  390. }
  391. });
  392. }
  393. // export
  394. function setText(Context, texts) { // 设置文本数据
  395. _app.log('进入设置文字方法, texts:' + JSON.stringify(texts));
  396. if (texts && _app.isArray(texts)) {
  397. _app.log('texts是数组');
  398. if (texts.length > 0) {
  399. for (let i = 0; i < texts.length; i++) {
  400. _app.log('字符串信息-初始化之前:' + JSON.stringify(texts[i]));
  401. texts[i] = setTextFn(Context, texts[i]);
  402. }
  403. }
  404. } else {
  405. _app.log('texts是对象');
  406. texts = setTextFn(Context, texts);
  407. }
  408. _app.log('返回texts:' + JSON.stringify(texts));
  409. return texts;
  410. }
  411. function setTextFn(Context, textItem) {
  412. _app.log('进入设置文字方法, textItem:' + JSON.stringify(textItem));
  413. if (_app.isNotNull_string(textItem.text)) {
  414. textItem.text = String(textItem.text);
  415. textItem.alpha = textItem.alpha !== undefined ? Number(textItem.alpha) : 1;
  416. textItem.color = textItem.color || 'black';
  417. textItem.size = textItem.size !== undefined ? Number(textItem.size) : 10;
  418. textItem.textAlign = textItem.textAlign || 'left';
  419. textItem.textBaseline = textItem.textBaseline || 'middle';
  420. textItem.dx = Number(textItem.dx) || 0;
  421. textItem.dy = Number(textItem.dy) || 0;
  422. textItem.size = Math.ceil(Number(textItem.size));
  423. _app.log('字符串信息-初始化默认值后:' + JSON.stringify(textItem));
  424. const textLength = countTextLength(Context, {
  425. text: textItem.text,
  426. size: textItem.size
  427. });
  428. _app.log('字符串信息-初始化时的文本长度:' + textLength);
  429. let infoCallBackObj = {};
  430. if (textItem.infoCallBack && typeof(textItem.infoCallBack) === 'function') {
  431. infoCallBackObj = textItem.infoCallBack(textLength);
  432. }
  433. textItem = {
  434. ...textItem,
  435. textLength,
  436. ...infoCallBackObj
  437. }
  438. _app.log('字符串信息-infoCallBack后:' + JSON.stringify(textItem));
  439. }
  440. return textItem;
  441. }
  442. function countTextLength(Context, obj) {
  443. _app.log('计算文字长度, obj:' + JSON.stringify(obj));
  444. const {
  445. text,
  446. size
  447. } = obj;
  448. Context.setFontSize(size);
  449. let textLength;
  450. try{
  451. textLength = Context.measureText(text); // 官方文档说 App端自定义组件编译模式暂时不可用measureText方法
  452. }catch(e){
  453. //TODO handle the exception
  454. textLength = {};
  455. }
  456. textLength = {};
  457. _app.log('measureText计算文字长度, textLength:' + JSON.stringify(textLength));
  458. textLength = textLength && textLength.width ? textLength.width : 0;
  459. if (!textLength) {
  460. let l = 0;
  461. for (let j = 0; j < text.length; j++) {
  462. let t = text.substr(j, 1);
  463. const countL = countStrLength(t);
  464. _app.log('计算文字宽度系数:' + countL);
  465. l += countL;
  466. }
  467. _app.log('文字宽度总系数:' + l);
  468. textLength = l * size;
  469. }
  470. return textLength;
  471. }
  472. //计算字符长度系数
  473. function countStrLength(t) {
  474. let l;
  475. if (/a/.test(t)) {
  476. l = 0.552734375
  477. } else if (/b/.test(t)) {
  478. l = 0.638671875
  479. } else if (/c/.test(t)) {
  480. l = 0.50146484375
  481. } else if (/d/.test(t)) {
  482. l = 0.6396484375
  483. } else if (/e/.test(t)) {
  484. l = 0.5673828125
  485. } else if (/f/.test(t)) {
  486. l = 0.3466796875
  487. } else if (/g/.test(t)) {
  488. l = 0.6396484375
  489. } else if (/h/.test(t)) {
  490. l = 0.61572265625
  491. } else if (/i/.test(t)) {
  492. l = 0.26611328125
  493. } else if (/j/.test(t)) {
  494. l = 0.26708984375
  495. } else if (/k/.test(t)) {
  496. l = 0.54443359375
  497. } else if (/l/.test(t)) {
  498. l = 0.26611328125
  499. } else if (/m/.test(t)) {
  500. l = 0.93701171875
  501. } else if (/n/.test(t)) {
  502. l = 0.6162109375
  503. } else if (/o/.test(t)) {
  504. l = 0.6357421875
  505. } else if (/p/.test(t)) {
  506. l = 0.638671875
  507. } else if (/q/.test(t)) {
  508. l = 0.6396484375
  509. } else if (/r/.test(t)) {
  510. l = 0.3818359375
  511. } else if (/s/.test(t)) {
  512. l = 0.462890625
  513. } else if (/t/.test(t)) {
  514. l = 0.37255859375
  515. } else if (/u/.test(t)) {
  516. l = 0.6162109375
  517. } else if (/v/.test(t)) {
  518. l = 0.52490234375
  519. } else if (/w/.test(t)) {
  520. l = 0.78955078125
  521. } else if (/x/.test(t)) {
  522. l = 0.5068359375
  523. } else if (/y/.test(t)) {
  524. l = 0.529296875
  525. } else if (/z/.test(t)) {
  526. l = 0.49169921875
  527. } else if (/A/.test(t)) {
  528. l = 0.70361328125
  529. } else if (/B/.test(t)) {
  530. l = 0.62744140625
  531. } else if (/C/.test(t)) {
  532. l = 0.6689453125
  533. } else if (/D/.test(t)) {
  534. l = 0.76171875
  535. } else if (/E/.test(t)) {
  536. l = 0.5498046875
  537. } else if (/F/.test(t)) {
  538. l = 0.53125
  539. } else if (/G/.test(t)) {
  540. l = 0.74365234375
  541. } else if (/H/.test(t)) {
  542. l = 0.7734375
  543. } else if (/I/.test(t)) {
  544. l = 0.2939453125
  545. } else if (/J/.test(t)) {
  546. l = 0.39599609375
  547. } else if (/K/.test(t)) {
  548. l = 0.634765625
  549. } else if (/L/.test(t)) {
  550. l = 0.51318359375
  551. } else if (/M/.test(t)) {
  552. l = 0.97705078125
  553. } else if (/N/.test(t)) {
  554. l = 0.81298828125
  555. } else if (/O/.test(t)) {
  556. l = 0.81494140625
  557. } else if (/P/.test(t)) {
  558. l = 0.61181640625
  559. } else if (/Q/.test(t)) {
  560. l = 0.81494140625
  561. } else if (/R/.test(t)) {
  562. l = 0.65283203125
  563. } else if (/S/.test(t)) {
  564. l = 0.5771484375
  565. } else if (/T/.test(t)) {
  566. l = 0.5732421875
  567. } else if (/U/.test(t)) {
  568. l = 0.74658203125
  569. } else if (/V/.test(t)) {
  570. l = 0.67626953125
  571. } else if (/W/.test(t)) {
  572. l = 1.017578125
  573. } else if (/X/.test(t)) {
  574. l = 0.64501953125
  575. } else if (/Y/.test(t)) {
  576. l = 0.603515625
  577. } else if (/Z/.test(t)) {
  578. l = 0.6201171875
  579. } else if (/[0-9]/.test(t)) {
  580. l = 0.58642578125
  581. } else if (/[\u4e00-\u9fa5]/.test(t)) {
  582. l = 1
  583. } else if (/ /.test(t)) {
  584. l = 0.2958984375
  585. } else if (/\`/.test(t)) {
  586. l = 0.294921875
  587. } else if (/\~/.test(t)) {
  588. l = 0.74169921875
  589. } else if (/\!/.test(t)) {
  590. l = 0.3125
  591. } else if (/\@/.test(t)) {
  592. l = 1.03125
  593. } else if (/\#/.test(t)) {
  594. l = 0.63818359375
  595. } else if (/\$/.test(t)) {
  596. l = 0.58642578125
  597. } else if (/\%/.test(t)) {
  598. l = 0.8896484375
  599. } else if (/\^/.test(t)) {
  600. l = 0.74169921875
  601. } else if (/\&/.test(t)) {
  602. l = 0.8701171875
  603. } else if (/\*/.test(t)) {
  604. l = 0.455078125
  605. } else if (/\(/.test(t)) {
  606. l = 0.333984375
  607. } else if (/\)/.test(t)) {
  608. l = 0.333984375
  609. } else if (/\_/.test(t)) {
  610. l = 0.4482421875
  611. } else if (/\-/.test(t)) {
  612. l = 0.4326171875
  613. } else if (/\+/.test(t)) {
  614. l = 0.74169921875
  615. } else if (/\=/.test(t)) {
  616. l = 0.74169921875
  617. } else if (/\|/.test(t)) {
  618. l = 0.26904296875
  619. } else if (/\\/.test(t)) {
  620. l = 0.416015625
  621. } else if (/\[/.test(t)) {
  622. l = 0.333984375
  623. } else if (/\]/.test(t)) {
  624. l = 0.333984375
  625. } else if (/\;/.test(t)) {
  626. l = 0.24072265625
  627. } else if (/\'/.test(t)) {
  628. l = 0.25634765625
  629. } else if (/\,/.test(t)) {
  630. l = 0.24072265625
  631. } else if (/\./.test(t)) {
  632. l = 0.24072265625
  633. } else if (/\//.test(t)) {
  634. l = 0.42724609375
  635. } else if (/\{/.test(t)) {
  636. l = 0.333984375
  637. } else if (/\}/.test(t)) {
  638. l = 0.333984375
  639. } else if (/\:/.test(t)) {
  640. l = 0.24072265625
  641. } else if (/\"/.test(t)) {
  642. l = 0.435546875
  643. } else if (/\</.test(t)) {
  644. l = 0.74169921875
  645. } else if (/\>/.test(t)) {
  646. l = 0.74169921875
  647. } else if (/\?/.test(t)) {
  648. l = 0.48291015625
  649. } else {
  650. l = 1
  651. }
  652. return l;
  653. }
  654. // export
  655. function setImage(images) { // 设置图片数据
  656. _app.log('进入设置图片数据方法');
  657. return new Promise(async (resolve, rejcet) => {
  658. try {
  659. if (images && _app.isArray(images)) {
  660. _app.log('images是一个数组');
  661. for (let i = 0; i < images.length; i++) {
  662. _app.log('设置图片数据循环中:' + i);
  663. images[i] = await setImageFn(images[i]);
  664. }
  665. } else {
  666. _app.log('images是一个对象');
  667. images = await setImageFn(images);
  668. }
  669. resolve(images);
  670. } catch (e) {
  671. //TODO handle the exception
  672. rejcet(e);
  673. }
  674. })
  675. }
  676. function setImageFn(image) {
  677. return new Promise(async (resolve, reject) => {
  678. if (image.url) {
  679. let imgUrl = image.url;
  680. imgUrl = await _app.downloadFile_PromiseFc(imgUrl);
  681. image.url = imgUrl;
  682. const hasinfoCallBack = image.infoCallBack && typeof(image.infoCallBack) === 'function';
  683. let imageInfo = {};
  684. imageInfo = await _app.getImageInfo_PromiseFc(imgUrl);
  685. if (hasinfoCallBack) {
  686. image = {
  687. ...image,
  688. ...image.infoCallBack(imageInfo)
  689. };
  690. }
  691. image.dx = Number(image.dx) || 0;
  692. image.dy = Number(image.dy) || 0;
  693. image.dWidth = Number(image.dWidth || imageInfo.width);
  694. image.dHeight = Number(image.dHeight || imageInfo.height);
  695. image = {
  696. ...image,
  697. imageInfo
  698. }
  699. }
  700. resolve(image);
  701. })
  702. }
  703. // export
  704. function drawText(Context, textArray, bgObj) { // 先遍历换行再绘制
  705. if (!_app.isArray(textArray)) {
  706. _app.log('遍历文本方法, 不是数组');
  707. textArray = [textArray];
  708. } else {
  709. _app.log('遍历文本方法, 是数组');
  710. }
  711. _app.log('遍历文本方法, textArray:' + JSON.stringify(textArray));
  712. const newArr = [];
  713. if (textArray && textArray.length > 0) {
  714. for (let j = 0; j < textArray.length; j++) {
  715. const textItem = textArray[j];
  716. if (textItem.text && textItem.lineFeed) {
  717. let lineNum = -1,
  718. maxWidth = bgObj.width,
  719. lineHeight = textItem.size,
  720. dx = textItem.dx;
  721. if (_app.isObject(textItem.lineFeed)) {
  722. const lineFeed = textItem.lineFeed;
  723. lineNum = (lineFeed.lineNum !== undefined && typeof(lineFeed.lineNum) === 'number') && lineFeed.lineNum >= 0 ?
  724. lineFeed.lineNum : lineNum;
  725. maxWidth = (lineFeed.maxWidth !== undefined && typeof(lineFeed.maxWidth) === 'number') ? lineFeed.maxWidth :
  726. maxWidth;
  727. lineHeight = (lineFeed.lineHeight !== undefined && typeof(lineFeed.lineHeight) === 'number') ? lineFeed.lineHeight :
  728. lineHeight;
  729. dx = (lineFeed.dx !== undefined && typeof(lineFeed.dx) === 'number') ? lineFeed.dx : dx;
  730. }
  731. const chr = (textItem.text).split("");
  732. let temp = "";
  733. const row = [];
  734. //循环出几行文字组成数组
  735. for (let a = 0, len = chr.length; a < len; a++) {
  736. if (countTextLength(Context, {
  737. text: temp,
  738. size: textItem.size
  739. }) <= maxWidth && countTextLength(Context, {
  740. text: (temp + chr[a]),
  741. size: textItem.size
  742. }) <= maxWidth) {
  743. temp += chr[a];
  744. if (a == (chr.length - 1)) {
  745. row.push(temp);
  746. }
  747. } else {
  748. row.push(temp);
  749. temp = chr[a];
  750. }
  751. }
  752. _app.log('循环出的文本数组:' + JSON.stringify(row));
  753. //只显示几行 变量间距lineHeight 变量行数lineNum
  754. let allNum = (lineNum >= 0 && lineNum < row.length) ? lineNum : row.length;
  755. for (let i = 0; i < allNum; i++) {
  756. let str = row[i];
  757. if (i == (allNum - 1) && allNum < row.length) {
  758. str = str.substring(0, str.length - 1) + '...';
  759. }
  760. const obj = { ...textItem,
  761. text: str,
  762. dx: i === 0 ? textItem.dx : (dx >= 0 ? dx : textItem.dx),
  763. dy: textItem.dy + (i * lineHeight),
  764. textLength: countTextLength(Context, {
  765. text: str,
  766. size: textItem.size
  767. })
  768. };
  769. _app.log('重新组成的文本对象:' + JSON.stringify(obj));
  770. newArr.push(obj);
  771. }
  772. } else {
  773. newArr.push(textItem);
  774. }
  775. }
  776. }
  777. _app.log('绘制文本新数组:' + JSON.stringify(newArr));
  778. drawTexts(Context, newArr);
  779. }
  780. function setFont(textItem = {}) {
  781. if (textItem.font && typeof(textItem.font) === 'string') {
  782. _app.log(textItem.font)
  783. return textItem.font;
  784. } else {
  785. let fontStyle = 'normal';
  786. let fontVariant = 'normal';
  787. let fontWeight = 'normal';
  788. let fontSize = textItem.size || 10;
  789. let fontFamily = 'sans-serif';
  790. fontSize = Math.ceil(Number(fontSize));
  791. if (textItem.fontStyle && typeof(textItem.fontStyle) === 'string')
  792. fontStyle = textItem.fontStyle.trim();
  793. if (textItem.fontVariant && typeof(textItem.fontVariant) === 'string')
  794. fontVariant = textItem.fontVariant.trim();
  795. if (textItem.fontWeight && (typeof(textItem.fontWeight) === 'string' || typeof(textItem.fontWeight) === 'number'))
  796. fontWeight = textItem.fontWeight.trim();
  797. if (textItem.fontFamily && typeof(textItem.fontFamily) === 'string')
  798. fontFamily = textItem.fontFamily.trim();
  799. return fontStyle + ' ' +
  800. fontVariant + ' ' +
  801. fontWeight + ' ' +
  802. fontSize + 'px' + ' ' +
  803. fontFamily;
  804. }
  805. }
  806. function drawTexts(Context, texts) { // 绘制文本
  807. _app.log('准备绘制文本方法, texts:' + JSON.stringify(texts));
  808. if (texts && _app.isArray(texts)) {
  809. _app.log('准备绘制文本方法, 是数组');
  810. if (texts.length > 0) {
  811. for (let i = 0; i < texts.length; i++) {
  812. drawTextFn(Context, texts[i]);
  813. }
  814. }
  815. } else {
  816. _app.log('准备绘制文本方法, 不是数组');
  817. drawTextFn(Context, texts);
  818. }
  819. }
  820. function drawTextFn(Context, textItem) {
  821. _app.log('进入绘制文本方法, textItem:' + JSON.stringify(textItem));
  822. if (textItem && _app.isObject(textItem) && textItem.text) {
  823. Context.font = setFont(textItem);
  824. Context.setFillStyle(textItem.color);
  825. Context.setGlobalAlpha(textItem.alpha);
  826. Context.setTextAlign(textItem.textAlign);
  827. Context.setTextBaseline(textItem.textBaseline);
  828. if (!textItem.maxLine) {
  829. Context.fillText(textItem.text, textItem.dx, textItem.dy);
  830. } else {
  831. fillTextWrap(Context, textItem.text, textItem.dx, textItem.dy, textItem.width * 0.9, 48, textItem.size)
  832. }
  833. if (textItem.lineThrough && _app.isObject(textItem.lineThrough)) {
  834. _app.log('有删除线');
  835. let lineThrough = textItem.lineThrough;
  836. lineThrough.alpha = lineThrough.alpha !== undefined ? lineThrough.alpha : textItem.alpha;
  837. lineThrough.style = lineThrough.style || textItem.color;
  838. lineThrough.width = lineThrough.width !== undefined ? lineThrough.width : textItem.size / 10;
  839. lineThrough.cap = lineThrough.cap !== undefined ? lineThrough.cap : 'butt';
  840. _app.log('删除线对象:' + JSON.stringify(lineThrough));
  841. Context.setGlobalAlpha(lineThrough.alpha);
  842. Context.setStrokeStyle(lineThrough.style);
  843. Context.setLineWidth(lineThrough.width);
  844. Context.setLineCap(lineThrough.cap);
  845. let mx, my;
  846. switch (textItem.textAlign) {
  847. case 'left':
  848. mx = textItem.dx;
  849. break;
  850. case 'center':
  851. mx = textItem.dx - (textItem.textLength) / 2;
  852. break;
  853. default:
  854. mx = textItem.dx - (textItem.textLength);
  855. break;
  856. }
  857. switch (textItem.textBaseline) {
  858. case 'top':
  859. my = textItem.dy + (textItem.size * .5);
  860. break;
  861. case 'middle':
  862. my = textItem.dy;
  863. break;
  864. default:
  865. my = textItem.dy - (textItem.size * .5);
  866. break;
  867. }
  868. Context.beginPath();
  869. Context.moveTo(mx, my);
  870. Context.lineTo(mx + textItem.textLength, my);
  871. Context.stroke();
  872. Context.closePath();
  873. _app.log('删除线完毕');
  874. }
  875. Context.setGlobalAlpha(1);
  876. Context.font = '10px sans-serif';
  877. }
  878. }
  879. /**
  880. * 海报文字换行
  881. */
  882. function fillTextWrap(ctx, text, x, y, maxWidth, lineHeight, fontSize) {
  883. // 默认参数
  884. maxWidth = maxWidth
  885. lineHeight = lineHeight || 20
  886. // 校验参数
  887. if (
  888. typeof text !== 'string' ||
  889. typeof x !== 'number' ||
  890. typeof y !== 'number'
  891. ) {
  892. return
  893. }
  894. // 字符串分割为数组
  895. const arrText = text.split('')
  896. // 当前字符串及宽度
  897. let currentText = ''
  898. let currentWidth
  899. let index = 0
  900. for (let letter of arrText) {
  901. currentText += letter
  902. currentWidth = ctx.measureText(currentText).width
  903. currentWidth = currentWidth || measureText(currentText, ctx, fontSize)
  904. if ((currentWidth > maxWidth) && (index < 2)) {
  905. if (index === 1) {
  906. currentText = currentText.substring(0, currentText.length - 1)
  907. currentText += ' ...'
  908. }
  909. ctx.fillText(currentText, x, y)
  910. currentText = ''
  911. y += lineHeight
  912. index += 1;
  913. }
  914. }
  915. if (currentText && index < 2) {
  916. ctx.fillText(currentText, x, y)
  917. }
  918. }
  919. function measureText(text, canvas, fontSize)
  920. {
  921. var text = text.split('');
  922. var width = 0;
  923. for (let i = 0; i < text.length; i++)
  924. {
  925. let item = text[i];
  926. if (/[a-zA-Z]/.test(item))
  927. {
  928. width += 7;
  929. } else if (/[0-9]/.test(item))
  930. {
  931. width += 5.5;
  932. } else if (/\./.test(item))
  933. {
  934. width += 2.7;
  935. } else if (/-/.test(item))
  936. {
  937. width += 3.25;
  938. } else if (/[\u4e00-\u9fa5]/.test(item))
  939. {
  940. width += 10;
  941. } else if (/\(|\)/.test(item))
  942. {
  943. width += 3.73;
  944. } else if (/\s/.test(item))
  945. {
  946. width += 2.5;
  947. } else if (/%/.test(item))
  948. {
  949. width += 8;
  950. } else
  951. {
  952. width += 10;
  953. }
  954. }
  955. return width * fontSize / 10;
  956. }
  957. // export
  958. function drawImage(Context, images) { // 绘制图片
  959. _app.log('判断图片数据类型:' + JSON.stringify(images))
  960. if (images && _app.isArray(images)) {
  961. if (images.length > 0) {
  962. for (let i = 0; i < images.length; i++) {
  963. readyDrawImageFn(Context, images[i]);
  964. }
  965. }
  966. } else {
  967. readyDrawImageFn(Context, images);
  968. }
  969. }
  970. function readyDrawImageFn(Context, img) {
  971. _app.log('判断绘制图片形状, img:' + JSON.stringify(img));
  972. if (img.url) {
  973. if (img.circleSet) {
  974. drawCircleImage(Context, img);
  975. } else if (img.roundRectSet) {
  976. drawRoundRectImage(Context, img);
  977. } else {
  978. drawImageFn(Context, img);
  979. }
  980. }
  981. }
  982. function drawImageFn(Context, img) {
  983. _app.log('进入绘制默认图片方法, img:' + JSON.stringify(img));
  984. if (img.url) {
  985. const hasAlpha = !_app.isUndef(img.alpha);
  986. img.alpha = Number(!_app.isUndef(img.alpha) ? img.alpha : 1);
  987. Context.setGlobalAlpha(img.alpha);
  988. _app.log('绘制默认图片方法, 有url');
  989. if (img.dWidth && img.dHeight && img.sx && img.sy && img.sWidth && img.sHeight) {
  990. _app.log('绘制默认图片方法, 绘制第一种方案');
  991. Context.drawImage(img.url, Number(img.dx || 0), Number(img.dy || 0),
  992. Number(img.dWidth) || false, Number(img.dHeight) || false,
  993. Number(img.sx) || false, Number(img.sy) || false,
  994. Number(img.sWidth) || false, Number(img.sHeight) || false);
  995. } else if (img.dWidth && img.dHeight) {
  996. _app.log('绘制默认图片方法, 绘制第二种方案');
  997. Context.drawImage(img.url, Number(img.dx || 0), Number(img.dy || 0),
  998. Number(img.dWidth) || false, Number(img.dHeight) || false);
  999. } else {
  1000. _app.log('绘制默认图片方法, 绘制第三种方案');
  1001. Context.drawImage(img.url, Number(img.dx || 0), Number(img.dy || 0));
  1002. }
  1003. if (hasAlpha) {
  1004. Context.setGlobalAlpha(1);
  1005. }
  1006. }
  1007. _app.log('绘制默认图片方法, 绘制完毕');
  1008. }
  1009. function drawCircleImage(Context, obj) {
  1010. _app.log('进入绘制圆形图片方法, obj:' + JSON.stringify(obj));
  1011. let {
  1012. dx,
  1013. dy,
  1014. dWidth,
  1015. dHeight,
  1016. circleSet,
  1017. imageInfo
  1018. } = obj;
  1019. let x, y, r;
  1020. if (typeof circleSet === 'object') {
  1021. x = circleSet.x;
  1022. y = circleSet.y;
  1023. r = circleSet.r;
  1024. }
  1025. if (!r) {
  1026. let d;
  1027. d = dWidth > dHeight ? dHeight : dWidth;
  1028. r = d / 2;
  1029. }
  1030. x = x ? dx + x : (dx || 0) + r;
  1031. y = y ? dy + y : (dy || 0) + r;
  1032. Context.save();
  1033. Context.beginPath();
  1034. Context.arc(x, y, r, 0, 2 * Math.PI, false);
  1035. Context.closePath();
  1036. Context.setGlobalAlpha(0);
  1037. Context.fillStyle = '#FFFFFF';
  1038. Context.fill();
  1039. Context.setGlobalAlpha(1);
  1040. Context.clip();
  1041. drawImageFn(Context, obj);
  1042. _app.log('默认图片绘制完毕');
  1043. Context.restore();
  1044. }
  1045. function drawRoundRectImage(Context, obj) { // 绘制矩形
  1046. _app.log('进入绘制矩形图片方法, obj:' + JSON.stringify(obj));
  1047. Context.save();
  1048. let {
  1049. dx,
  1050. dy,
  1051. dWidth,
  1052. dHeight,
  1053. roundRectSet,
  1054. imageInfo
  1055. } = obj;
  1056. let r;
  1057. if (typeof roundRectSet === 'object') {
  1058. r = roundRectSet.r;
  1059. }
  1060. r = r || dWidth * .1;
  1061. if (dWidth < 2 * r) {
  1062. r = dWidth / 2;
  1063. }
  1064. if (dHeight < 2 * r) {
  1065. r = dHeight / 2;
  1066. }
  1067. Context.beginPath();
  1068. Context.moveTo(dx + r, dy);
  1069. Context.arcTo(dx + dWidth, dy, dx + dWidth, dy + dHeight, r);
  1070. Context.arcTo(dx + dWidth, dy + dHeight, dx, dy + dHeight, r);
  1071. Context.arcTo(dx, dy + dHeight, dx, dy, r);
  1072. Context.arcTo(dx, dy, dx + dWidth, dy, r);
  1073. Context.closePath();
  1074. Context.setGlobalAlpha(0);
  1075. Context.fillStyle = '#FFFFFF';
  1076. Context.fill();
  1077. Context.setGlobalAlpha(1);
  1078. Context.clip();
  1079. drawImageFn(Context, obj);
  1080. Context.restore();
  1081. _app.log('进入绘制矩形图片方法, 绘制完毕');
  1082. }
  1083. // export
  1084. function drawQrCode(Context, qrCodeObj) { //生成二维码方法, 参考了 诗小柒 的二维码生成器代码
  1085. _app.log('进入绘制二维码方法')
  1086. _app.showLoading('正在生成二维码');
  1087. let qrcodeAlgObjCache = [];
  1088. let options = {
  1089. text: String(qrCodeObj.text || '') || '', // 生成内容
  1090. size: Number(qrCodeObj.size || 0) || 200, // 二维码大小
  1091. background: String(qrCodeObj.background || '') || '#ffffff', // 背景色
  1092. foreground: String(qrCodeObj.foreground || '') || '#000000', // 前景色
  1093. pdground: String(qrCodeObj.pdground || '') || '#000000', // 定位角点颜色
  1094. correctLevel: Number(qrCodeObj.correctLevel || 0) || 3, // 容错级别
  1095. image: String(qrCodeObj.image || '') || '', // 二维码图标
  1096. imageSize: Number(qrCodeObj.imageSize || 0) || 40, // 二维码图标大小
  1097. dx: Number(qrCodeObj.dx || 0) || 0, // x轴距离
  1098. dy: Number(qrCodeObj.dy || 0) || 0 // y轴距离
  1099. }
  1100. let qrCodeAlg = null;
  1101. let d = 0;
  1102. for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
  1103. d = i;
  1104. if (qrcodeAlgObjCache[i].text == options.text && qrcodeAlgObjCache[i].text.correctLevel == options.correctLevel) {
  1105. qrCodeAlg = qrcodeAlgObjCache[i].obj;
  1106. break;
  1107. }
  1108. }
  1109. if (d == l) {
  1110. qrCodeAlg = new QRCodeAlg(options.text, options.correctLevel);
  1111. qrcodeAlgObjCache.push({
  1112. text: options.text,
  1113. correctLevel: options.correctLevel,
  1114. obj: qrCodeAlg
  1115. });
  1116. }
  1117. let getForeGround = function(config) {
  1118. let options = config.options;
  1119. if (options.pdground && (
  1120. (config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
  1121. (config.row > (config.count - 6) && config.row < (config.count - 2) && config.col > 1 && config.col < 5) ||
  1122. (config.row > 1 && config.row < 5 && config.col > (config.count - 6) && config.col < (config.count - 2))
  1123. )) {
  1124. return options.pdground;
  1125. }
  1126. return options.foreground;
  1127. }
  1128. let count = qrCodeAlg.getModuleCount();
  1129. let ratioSize = options.size;
  1130. let ratioImgSize = options.imageSize;
  1131. //计算每个点的长宽
  1132. let tileW = (ratioSize / count).toPrecision(4);
  1133. let tileH = (ratioSize / count).toPrecision(4);
  1134. //绘制
  1135. for (let row = 0; row < count; row++) {
  1136. for (let col = 0; col < count; col++) {
  1137. let w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW));
  1138. let h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW));
  1139. let foreground = getForeGround({
  1140. row: row,
  1141. col: col,
  1142. count: count,
  1143. options: options
  1144. });
  1145. Context.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background);
  1146. Context.fillRect(options.dx + Math.round(col * tileW), options.dy + Math.round(row * tileH), w, h);
  1147. }
  1148. }
  1149. if (options.image) {
  1150. let x = options.dx + Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
  1151. let y = options.dy + Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
  1152. drawRoundedRect(Context, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
  1153. Context.drawImage(options.image, x, y, ratioImgSize, ratioImgSize);
  1154. // 画圆角矩形
  1155. function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
  1156. ctxi.setLineWidth(lineWidth);
  1157. ctxi.setFillStyle(options.background);
  1158. ctxi.setStrokeStyle(options.background);
  1159. ctxi.beginPath(); // draw top and top right corner
  1160. ctxi.moveTo(x + r, y);
  1161. ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner
  1162. ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner
  1163. ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner
  1164. ctxi.arcTo(x, y, x + r, y, r);
  1165. ctxi.closePath();
  1166. if (fill) {
  1167. ctxi.fill();
  1168. }
  1169. if (stroke) {
  1170. ctxi.stroke();
  1171. }
  1172. }
  1173. }
  1174. _app.log('进入绘制二维码方法完毕')
  1175. _app.hideLoading();
  1176. }
  1177. function getShreUserPosterBackground(objs) { //检查背景图是否存在于本地, 若存在直接返回, 否则调用getShreUserPosterBackgroundFc方法
  1178. let {
  1179. backgroundImage,
  1180. type
  1181. } = objs;
  1182. return new Promise(async (resolve, reject) => {
  1183. try {
  1184. _app.showLoading('正在获取海报背景图');
  1185. const savedFilePath = await getShreUserPosterBackgroundFc(objs)
  1186. _app.hideLoading();
  1187. resolve(savedFilePath);
  1188. } catch (e) {
  1189. _app.hideLoading();
  1190. _app.showToast('获取分享用户背景图失败:' + JSON.stringify(e));
  1191. _app.log(JSON.stringify(e));
  1192. reject(e);
  1193. }
  1194. })
  1195. }
  1196. function getPosterStorage(type) {
  1197. return _app.getStorageSync(getStorageKey(type));
  1198. }
  1199. function removePosterStorage(type) {
  1200. const ShreUserPosterBackgroundKey = getStorageKey(type);
  1201. const pbg = _app.getStorageSync(ShreUserPosterBackgroundKey);
  1202. if (pbg && pbg.path) {
  1203. _app.removeStorageSync(ShreUserPosterBackgroundKey);
  1204. }
  1205. }
  1206. function setPosterStorage(type, data) {
  1207. _app.setStorage(getStorageKey(type), data);
  1208. }
  1209. function getStorageKey(type) {
  1210. return ShreUserPosterBackgroundKey + (type || 'default');
  1211. }
  1212. function getShreUserPosterBackgroundFc(objs, upimage) { //下载并保存背景图方法
  1213. let {
  1214. backgroundImage,
  1215. type
  1216. } = objs;
  1217. _app.log('获取分享背景图, 尝试清空本地数据');
  1218. return new Promise(async (resolve, reject) => {
  1219. try {
  1220. _app.showLoading('正在下载海报背景图');
  1221. if (upimage) {
  1222. _app.log('有从后端获取的背景图片路径');
  1223. _app.log('尝试下载并保存背景图');
  1224. const name = _app.fileNameInPath(upimage);
  1225. const savedFilePath = await _app.downLoadAndSaveFile_PromiseFc(upimage);
  1226. if (savedFilePath) {
  1227. _app.log('下载并保存背景图成功:' + savedFilePath);
  1228. const imageObj = await _app.getImageInfo_PromiseFc(savedFilePath);
  1229. const returnObj = {
  1230. path: savedFilePath,
  1231. width: imageObj.width,
  1232. height: imageObj.height,
  1233. name
  1234. }
  1235. // #ifndef H5
  1236. setPosterStorage(type, { ...returnObj
  1237. });
  1238. // #endif
  1239. _app.hideLoading();
  1240. resolve(returnObj);
  1241. } else {
  1242. _app.hideLoading();
  1243. reject('not find savedFilePath');
  1244. }
  1245. } else {
  1246. _app.log('没有从后端获取的背景图片路径, 尝试从后端获取背景图片路径');
  1247. const image = await _app.getPosterUrl(objs);
  1248. _app.log('尝试下载并保存背景图:' + image);
  1249. const savedFilePath = await _app.downLoadAndSaveFile_PromiseFc(image);
  1250. if (savedFilePath) {
  1251. _app.log('下载并保存背景图成功:' + savedFilePath);
  1252. const imageObj = await _app.getImageInfo_PromiseFc(savedFilePath);
  1253. _app.log('获取图片信息成功');
  1254. const returnObj = {
  1255. path: savedFilePath,
  1256. width: imageObj.width,
  1257. height: imageObj.height,
  1258. name: _app.fileNameInPath(image)
  1259. }
  1260. _app.log('拼接背景图信息对象成功:' + JSON.stringify(returnObj));
  1261. // #ifndef H5
  1262. setPosterStorage(type, { ...returnObj
  1263. });
  1264. // #endif
  1265. _app.hideLoading();
  1266. _app.log('返回背景图信息对象');
  1267. resolve({ ...returnObj
  1268. });
  1269. } else {
  1270. _app.hideLoading();
  1271. reject('not find savedFilePath');
  1272. }
  1273. }
  1274. } catch (e) {
  1275. //TODO handle the exception
  1276. reject(e);
  1277. }
  1278. });
  1279. }
  1280. module.exports = {
  1281. getSharePoster,
  1282. setText,
  1283. setImage,
  1284. drawText,
  1285. drawImage,
  1286. drawQrCode
  1287. }