QS-SharePoster.js 36 KB

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