123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332 |
- /* eslint-disable */
- import _app from './app.js';
- import QRCodeAlg from './QRCodeAlg.js';
- const ShreUserPosterBackgroundKey = 'ShrePosterBackground_'; // 背景图片缓存名称前缀
- const idKey = 'QSSHAREPOSTER_IDKEY'; //drawArray自动生成的idkey
- var isMp = false;
- // #ifdef MP
- isMp = true;
- // #endif
- var nbgScale = 1;
- // export default
- function getSharePoster(obj) {
- return new Promise(async (resolve, reject) => {
- try {
- const result1 = await returnPromise(obj);
- resolve(result1);
- } catch (e) {
- //TODO handle the exception
- try {
- if(obj.bgScale) {
- obj.bgScale = Number(obj.bgScale) - 0.1
- }else{
- nbgScale = nbgScale - 0.1
- }
- _app.log('------------清除缓存后, 开始第二次尝试------------');
- const result2 = await returnPromise(obj);
- resolve(result2);
- } catch (e) {
- //TODO handle the exception
- reject(e);
- }
- }
- })
- }
- function returnPromise(obj) {
- let {
- type,
- formData,
- background,
- posterCanvasId,
- backgroundImage,
- reserve,
- textArray,
- drawArray,
- qrCodeArray,
- imagesArray,
- setCanvasWH,
- setCanvasToTempFilePath,
- setDraw,
- bgScale,
- Context,
- _this,
- delayTimeScale,
- drawDelayTime
- } = obj;
- return new Promise(async (rs, rj) => {
- try {
- _app.showLoading('正在准备海报数据');
- if (!Context) {
- _app.log('没有画布对象,创建画布对象');
- Context = uni.createCanvasContext(posterCanvasId, (_this || null));
- }
- let bgObj;
- if (background && background.width && background.height) {
- bgObj = background;
- } else {
- bgObj = await getShreUserPosterBackground({
- backgroundImage,
- type,
- formData
- });
- }
- bgScale = bgScale || nbgScale;
- bgObj.width = bgObj.width * bgScale;
- bgObj.height = bgObj.height * bgScale;
- _app.log('获取背景图信息对象成功:' + JSON.stringify(bgObj));
- const params = {
- bgObj,
- type,
- bgScale
- };
- if (setCanvasWH && typeof(setCanvasWH) == 'function') {
- await new Promise((resolve, reject)=>{
- setCanvasWH(params);
- setTimeout(()=>{
- resolve();
- }, 0)
- })
- }
- if (imagesArray) {
- if (typeof(imagesArray) == 'function')
- imagesArray = imagesArray(params);
- _app.showLoading('正在生成需绘制图片的临时路径');
- _app.log('准备设置图片');
- imagesArray = await setImage(imagesArray);
- _app.hideLoading();
- }
- if (textArray) {
- if (typeof(textArray) == 'function')
- textArray = textArray(params);
- textArray = setText(Context, textArray);
- }
- if (qrCodeArray) {
- if (typeof(qrCodeArray) == 'function')
- qrCodeArray = qrCodeArray(params);
- _app.showLoading('正在生成需绘制图片的临时路径');
- for (let i = 0; i < qrCodeArray.length; i++) {
- _app.log(i);
- if (qrCodeArray[i].image)
- qrCodeArray[i].image = await _app.downloadFile_PromiseFc(qrCodeArray[i].image);
- }
- _app.hideLoading();
- }
- if (drawArray) {
- if (typeof(drawArray) == 'function') {
- drawArray = drawArray(params);
- }
- if (_app.isPromise(drawArray)) {
- drawArray = await drawArray;
- }
- if (_app.isArray(drawArray) && drawArray.length > 0) {
- let hasAllInfoCallback = false;
- for (let i = 0; i < drawArray.length; i++) {
- const drawArrayItem = drawArray[i];
- if (_app.isFn(drawArrayItem.allInfoCallback) && !hasAllInfoCallback) hasAllInfoCallback = true;
- drawArrayItem[idKey] = i;
- let newData;
- switch (drawArrayItem.type) {
- case 'image':
- newData = await setImage(drawArrayItem);
- break;
- case 'text':
- newData = setText(Context, drawArrayItem);
- break;
- case 'qrcode':
- if (drawArrayItem.image)
- newData = {
- image: await _app.downloadFile_PromiseFc(drawArrayItem.image)
- };
- break;
- case 'custom':
- break;
- default:
- _app.log('未识别的类型');
- break;
- }
- if (newData && _app.isObject(newData)) {
- drawArray[i] = { ...drawArrayItem,
- ...newData
- }
- };
- }
- if (hasAllInfoCallback) {
- _app.log('----------------hasAllInfoCallback----------------');
- const drawArray_copy = [...drawArray];
- drawArray_copy.sort((a, b) => {
- const a_serialNum = !_app.isUndef(a.serialNum) && !_app.isNull(a.serialNum) ? Number(a.serialNum) : Number.NEGATIVE_INFINITY;
- const b_serialNum = !_app.isUndef(b.serialNum) && !_app.isNull(b.serialNum) ? Number(b.serialNum) : Number.NEGATIVE_INFINITY;
- return a_serialNum - b_serialNum;
- })
- _app.log('开始for循环');
- for (let i = 0; i < drawArray_copy.length; i++) {
- const item = { ...drawArray_copy[i]
- };
- if (_app.isFn(item.allInfoCallback)) {
- let newData = item.allInfoCallback({
- drawArray
- });
- if (_app.isPromise(newData)) newData = await newData;
- const item_idKey = item[idKey];
- if (!_app.isUndef(item_idKey)) {
- drawArray[item[idKey]] = { ...item,
- ...newData
- };
- } else {
- console.log('程序错误 找不到idKey!!! ...这不应该啊');
- }
- }
- }
- _app.log('for循环结束');
- }
- }
- }
- const poster = await drawShareImage({
- Context,
- type,
- posterCanvasId,
- reserve,
- drawArray,
- textArray,
- imagesArray,
- bgObj,
- qrCodeArray,
- setCanvasToTempFilePath,
- setDraw,
- bgScale,
- _this,
- delayTimeScale,
- drawDelayTime
- });
- _app.hideLoading();
- rs({
- bgObj,
- poster,
- type
- });
- } catch (e) {
- //TODO handle the exception
- rj(e);
- }
- });
- }
- function drawShareImage(obj) { //绘制海报方法
- let {
- Context,
- type,
- posterCanvasId,
- reserve,
- bgObj,
- drawArray,
- textArray,
- qrCodeArray,
- imagesArray,
- setCanvasToTempFilePath,
- setDraw,
- bgScale,
- _this,
- delayTimeScale,
- drawDelayTime
- } = obj;
- const params = {
- Context,
- bgObj,
- type,
- bgScale
- };
- delayTimeScale = delayTimeScale !== undefined ? delayTimeScale : 15;
- drawDelayTime = drawDelayTime !== undefined ? drawDelayTime : 100;
- return new Promise((rs, rj) => {
- try {
- _app.showLoading('正在绘制海报');
- _app.log('背景对象:' + JSON.stringify(bgObj));
- if (bgObj && bgObj.path) {
- _app.log('背景有图片路径');
- Context.drawImage(bgObj.path, 0, 0, bgObj.width, bgObj.height);
- } else {
- _app.log('背景没有图片路径');
- if (bgObj.backgroundColor) {
- _app.log('背景有背景颜色:' + bgObj.backgroundColor);
- Context.setFillStyle(bgObj.backgroundColor);
- Context.fillRect(0, 0, bgObj.width, bgObj.height);
- } else {
- _app.log('背景没有背景颜色');
- }
- }
- _app.showLoading('绘制图片');
- if (imagesArray && imagesArray.length > 0)
- drawImage(Context, imagesArray);
- _app.showLoading('绘制自定义内容');
- if (setDraw && typeof(setDraw) == 'function') setDraw(params);
- _app.showLoading('绘制文本');
- if (textArray && textArray.length > 0)
- drawText(Context, textArray, bgObj);
- _app.showLoading('绘制二维码');
- if (qrCodeArray && qrCodeArray.length > 0) {
- for (let i = 0; i < qrCodeArray.length; i++) {
- drawQrCode(Context, qrCodeArray[i]);
- }
- }
- _app.showLoading('绘制可控层级序列');
- if (drawArray && drawArray.length > 0) {
- for (let i = 0; i < drawArray.length; i++) {
- const drawArrayItem = drawArray[i];
- _app.log('绘制可控层级序列, drawArrayItem:' + JSON.stringify(drawArrayItem));
- switch (drawArrayItem.type) {
- case 'image':
- _app.log('绘制可控层级序列, 绘制图片');
- drawImage(Context, drawArrayItem);
- break;
- case 'text':
- _app.log('绘制可控层级序列, 绘制文本');
- drawText(Context, drawArrayItem, bgObj);
- break;
- case 'qrcode':
- _app.log('绘制可控层级序列, 绘制二维码');
- drawQrCode(Context, drawArrayItem);
- break;
- case 'custom':
- _app.log('绘制可控层级序列, 绘制自定义内容');
- if (drawArrayItem.setDraw && typeof drawArrayItem.setDraw === 'function')
- drawArrayItem.setDraw(Context);
- break;
- default:
- _app.log('未识别的类型');
- break;
- }
- }
- }
- _app.showLoading('绘制中')
- setTimeout(() => {
- _app.log('准备执行draw方法')
- _app.log('Context:' + Context);
- const fn = function(){
- _app.showLoading('正在绘制海报');
- let setObj = setCanvasToTempFilePath || {};
- if (setObj && typeof(setObj) == 'function')
- setObj = setCanvasToTempFilePath(bgObj, type);
- let canvasToTempFilePathFn;
- // #ifdef H5
- canvasToTempFilePathFn = function() {
- _app.hideLoading();
- rs({
- tempFilePath: document.querySelector(`uni-canvas[canvas-id=${posterCanvasId}]>canvas`).toDataURL(
- `image/${setObj.fileType||'jpg'}`, setObj.quality || .8)
- });
- }
- // #endif
- // #ifndef H5
- const data = {
- x: 0,
- y: 0,
- width: bgObj.width,
- height: bgObj.height,
- destWidth: bgObj.width * 2, // 若H5使用这里请不要乘以二
- destHeight: bgObj.height * 2, // 若H5使用这里请不要乘以二
- quality: .8,
- fileType: 'jpg',
- ...setObj
- };
- _app.log('canvasToTempFilePath的data对象:' + JSON.stringify(data));
- canvasToTempFilePathFn = function() {
- const toTempFilePathObj = { //输出为图片
- ...data,
- canvasId: posterCanvasId,
- success(res) {
- _app.hideLoading();
- rs(res);
- },
- fail(err) {
- _app.hideLoading();
- _app.log('输出图片失败:' + JSON.stringify(err));
- rj('输出图片失败:' + JSON.stringify(err))
- }
- }
- uni.canvasToTempFilePath(toTempFilePathObj, _this || null);
- }
- // #endif
- let delayTime = 0;
- if (qrCodeArray) {
- qrCodeArray.forEach(item => {
- if (item.text) {
- delayTime += Number(item.text.length);
- }
- })
- }
- if (imagesArray) {
- imagesArray.forEach(() => {
- delayTime += delayTimeScale;
- })
- }
- if (textArray) {
- textArray.forEach(() => {
- delayTime += delayTimeScale;
- })
- }
- if (drawArray) {
- drawArray.forEach(item => {
- switch (item.type) {
- case 'text':
- if (item.text) {
- delayTime += item.text.length;
- }
- break;
- default:
- delayTime += delayTimeScale;
- break;
- }
- })
- }
- _app.log('延时系数:' + delayTimeScale);
- _app.log('总计延时:' + delayTime);
- setTimeout(canvasToTempFilePathFn, delayTime);
- }
- Context.draw((typeof(reserve) == 'boolean' ? reserve : false), fn);
- }, drawDelayTime);
- } catch (e) {
- //TODO handle the exception
- _app.hideLoading();
- rj(e);
- }
- });
- }
- // export
- function setText(Context, texts) { // 设置文本数据
- _app.log('进入设置文字方法, texts:' + JSON.stringify(texts));
- if (texts && _app.isArray(texts)) {
- _app.log('texts是数组');
- if (texts.length > 0) {
- for (let i = 0; i < texts.length; i++) {
- _app.log('字符串信息-初始化之前:' + JSON.stringify(texts[i]));
- texts[i] = setTextFn(Context, texts[i]);
- }
- }
- } else {
- _app.log('texts是对象');
- texts = setTextFn(Context, texts);
- }
- _app.log('返回texts:' + JSON.stringify(texts));
- return texts;
- }
- function setTextFn(Context, textItem) {
- _app.log('进入设置文字方法, textItem:' + JSON.stringify(textItem));
- if (_app.isNotNull_string(textItem.text)) {
- textItem.text = String(textItem.text);
- textItem.alpha = textItem.alpha !== undefined ? Number(textItem.alpha) : 1;
- textItem.color = textItem.color || 'black';
- textItem.size = textItem.size !== undefined ? Number(textItem.size) : 10;
- textItem.textAlign = textItem.textAlign || 'left';
- textItem.textBaseline = textItem.textBaseline || 'middle';
- textItem.dx = Number(textItem.dx) || 0;
- textItem.dy = Number(textItem.dy) || 0;
- textItem.size = Math.ceil(Number(textItem.size));
- _app.log('字符串信息-初始化默认值后:' + JSON.stringify(textItem));
- const textLength = countTextLength(Context, {
- text: textItem.text,
- size: textItem.size
- });
- _app.log('字符串信息-初始化时的文本长度:' + textLength);
- let infoCallBackObj = {};
- if (textItem.infoCallBack && typeof(textItem.infoCallBack) === 'function') {
- infoCallBackObj = textItem.infoCallBack(textLength);
- }
- textItem = {
- ...textItem,
- textLength,
- ...infoCallBackObj
- }
- _app.log('字符串信息-infoCallBack后:' + JSON.stringify(textItem));
- }
- return textItem;
- }
- function countTextLength(Context, obj) {
- _app.log('计算文字长度, obj:' + JSON.stringify(obj));
- const {
- text,
- size
- } = obj;
- Context.setFontSize(size);
- let textLength;
- try{
- textLength = Context.measureText(text); // 官方文档说 App端自定义组件编译模式暂时不可用measureText方法
- }catch(e){
- //TODO handle the exception
- textLength = {};
- }
- textLength = {};
- _app.log('measureText计算文字长度, textLength:' + JSON.stringify(textLength));
- textLength = textLength && textLength.width ? textLength.width : 0;
- if (!textLength) {
- let l = 0;
- for (let j = 0; j < text.length; j++) {
- let t = text.substr(j, 1);
- const countL = countStrLength(t);
- _app.log('计算文字宽度系数:' + countL);
- l += countL;
- }
- _app.log('文字宽度总系数:' + l);
- textLength = l * size;
- }
- return textLength;
- }
- //计算字符长度系数
- function countStrLength(t) {
- let l;
- if (/a/.test(t)) {
- l = 0.552734375
- } else if (/b/.test(t)) {
- l = 0.638671875
- } else if (/c/.test(t)) {
- l = 0.50146484375
- } else if (/d/.test(t)) {
- l = 0.6396484375
- } else if (/e/.test(t)) {
- l = 0.5673828125
- } else if (/f/.test(t)) {
- l = 0.3466796875
- } else if (/g/.test(t)) {
- l = 0.6396484375
- } else if (/h/.test(t)) {
- l = 0.61572265625
- } else if (/i/.test(t)) {
- l = 0.26611328125
- } else if (/j/.test(t)) {
- l = 0.26708984375
- } else if (/k/.test(t)) {
- l = 0.54443359375
- } else if (/l/.test(t)) {
- l = 0.26611328125
- } else if (/m/.test(t)) {
- l = 0.93701171875
- } else if (/n/.test(t)) {
- l = 0.6162109375
- } else if (/o/.test(t)) {
- l = 0.6357421875
- } else if (/p/.test(t)) {
- l = 0.638671875
- } else if (/q/.test(t)) {
- l = 0.6396484375
- } else if (/r/.test(t)) {
- l = 0.3818359375
- } else if (/s/.test(t)) {
- l = 0.462890625
- } else if (/t/.test(t)) {
- l = 0.37255859375
- } else if (/u/.test(t)) {
- l = 0.6162109375
- } else if (/v/.test(t)) {
- l = 0.52490234375
- } else if (/w/.test(t)) {
- l = 0.78955078125
- } else if (/x/.test(t)) {
- l = 0.5068359375
- } else if (/y/.test(t)) {
- l = 0.529296875
- } else if (/z/.test(t)) {
- l = 0.49169921875
- } else if (/A/.test(t)) {
- l = 0.70361328125
- } else if (/B/.test(t)) {
- l = 0.62744140625
- } else if (/C/.test(t)) {
- l = 0.6689453125
- } else if (/D/.test(t)) {
- l = 0.76171875
- } else if (/E/.test(t)) {
- l = 0.5498046875
- } else if (/F/.test(t)) {
- l = 0.53125
- } else if (/G/.test(t)) {
- l = 0.74365234375
- } else if (/H/.test(t)) {
- l = 0.7734375
- } else if (/I/.test(t)) {
- l = 0.2939453125
- } else if (/J/.test(t)) {
- l = 0.39599609375
- } else if (/K/.test(t)) {
- l = 0.634765625
- } else if (/L/.test(t)) {
- l = 0.51318359375
- } else if (/M/.test(t)) {
- l = 0.97705078125
- } else if (/N/.test(t)) {
- l = 0.81298828125
- } else if (/O/.test(t)) {
- l = 0.81494140625
- } else if (/P/.test(t)) {
- l = 0.61181640625
- } else if (/Q/.test(t)) {
- l = 0.81494140625
- } else if (/R/.test(t)) {
- l = 0.65283203125
- } else if (/S/.test(t)) {
- l = 0.5771484375
- } else if (/T/.test(t)) {
- l = 0.5732421875
- } else if (/U/.test(t)) {
- l = 0.74658203125
- } else if (/V/.test(t)) {
- l = 0.67626953125
- } else if (/W/.test(t)) {
- l = 1.017578125
- } else if (/X/.test(t)) {
- l = 0.64501953125
- } else if (/Y/.test(t)) {
- l = 0.603515625
- } else if (/Z/.test(t)) {
- l = 0.6201171875
- } else if (/[0-9]/.test(t)) {
- l = 0.58642578125
- } else if (/[\u4e00-\u9fa5]/.test(t)) {
- l = 1
- } else if (/ /.test(t)) {
- l = 0.2958984375
- } else if (/\`/.test(t)) {
- l = 0.294921875
- } else if (/\~/.test(t)) {
- l = 0.74169921875
- } else if (/\!/.test(t)) {
- l = 0.3125
- } else if (/\@/.test(t)) {
- l = 1.03125
- } else if (/\#/.test(t)) {
- l = 0.63818359375
- } else if (/\$/.test(t)) {
- l = 0.58642578125
- } else if (/\%/.test(t)) {
- l = 0.8896484375
- } else if (/\^/.test(t)) {
- l = 0.74169921875
- } else if (/\&/.test(t)) {
- l = 0.8701171875
- } else if (/\*/.test(t)) {
- l = 0.455078125
- } else if (/\(/.test(t)) {
- l = 0.333984375
- } else if (/\)/.test(t)) {
- l = 0.333984375
- } else if (/\_/.test(t)) {
- l = 0.4482421875
- } else if (/\-/.test(t)) {
- l = 0.4326171875
- } else if (/\+/.test(t)) {
- l = 0.74169921875
- } else if (/\=/.test(t)) {
- l = 0.74169921875
- } else if (/\|/.test(t)) {
- l = 0.26904296875
- } else if (/\\/.test(t)) {
- l = 0.416015625
- } else if (/\[/.test(t)) {
- l = 0.333984375
- } else if (/\]/.test(t)) {
- l = 0.333984375
- } else if (/\;/.test(t)) {
- l = 0.24072265625
- } else if (/\'/.test(t)) {
- l = 0.25634765625
- } else if (/\,/.test(t)) {
- l = 0.24072265625
- } else if (/\./.test(t)) {
- l = 0.24072265625
- } else if (/\//.test(t)) {
- l = 0.42724609375
- } else if (/\{/.test(t)) {
- l = 0.333984375
- } else if (/\}/.test(t)) {
- l = 0.333984375
- } else if (/\:/.test(t)) {
- l = 0.24072265625
- } else if (/\"/.test(t)) {
- l = 0.435546875
- } else if (/\</.test(t)) {
- l = 0.74169921875
- } else if (/\>/.test(t)) {
- l = 0.74169921875
- } else if (/\?/.test(t)) {
- l = 0.48291015625
- } else {
- l = 1
- }
- return l;
- }
- // export
- function setImage(images) { // 设置图片数据
- _app.log('进入设置图片数据方法');
- return new Promise(async (resolve, rejcet) => {
- try {
- if (images && _app.isArray(images)) {
- _app.log('images是一个数组');
- for (let i = 0; i < images.length; i++) {
- _app.log('设置图片数据循环中:' + i);
- images[i] = await setImageFn(images[i]);
- }
- } else {
- _app.log('images是一个对象');
- images = await setImageFn(images);
- }
- resolve(images);
- } catch (e) {
- //TODO handle the exception
- rejcet(e);
- }
- })
- }
- function setImageFn(image) {
- return new Promise(async (resolve, reject) => {
- if (image.url) {
- let imgUrl = image.url;
- imgUrl = await _app.downloadFile_PromiseFc(imgUrl);
- image.url = imgUrl;
- const hasinfoCallBack = image.infoCallBack && typeof(image.infoCallBack) === 'function';
- let imageInfo = {};
- imageInfo = await _app.getImageInfo_PromiseFc(imgUrl);
- if (hasinfoCallBack) {
- image = {
- ...image,
- ...image.infoCallBack(imageInfo)
- };
- }
- image.dx = Number(image.dx) || 0;
- image.dy = Number(image.dy) || 0;
- image.dWidth = Number(image.dWidth || imageInfo.width);
- image.dHeight = Number(image.dHeight || imageInfo.height);
- image = {
- ...image,
- imageInfo
- }
- }
- resolve(image);
- })
- }
- // export
- function drawText(Context, textArray, bgObj) { // 先遍历换行再绘制
- if (!_app.isArray(textArray)) {
- _app.log('遍历文本方法, 不是数组');
- textArray = [textArray];
- } else {
- _app.log('遍历文本方法, 是数组');
- }
- _app.log('遍历文本方法, textArray:' + JSON.stringify(textArray));
- const newArr = [];
- if (textArray && textArray.length > 0) {
- for (let j = 0; j < textArray.length; j++) {
- const textItem = textArray[j];
- if (textItem.text && textItem.lineFeed) {
- let lineNum = -1,
- maxWidth = bgObj.width,
- lineHeight = textItem.size,
- dx = textItem.dx;
- if (_app.isObject(textItem.lineFeed)) {
- const lineFeed = textItem.lineFeed;
- lineNum = (lineFeed.lineNum !== undefined && typeof(lineFeed.lineNum) === 'number') && lineFeed.lineNum >= 0 ?
- lineFeed.lineNum : lineNum;
- maxWidth = (lineFeed.maxWidth !== undefined && typeof(lineFeed.maxWidth) === 'number') ? lineFeed.maxWidth :
- maxWidth;
- lineHeight = (lineFeed.lineHeight !== undefined && typeof(lineFeed.lineHeight) === 'number') ? lineFeed.lineHeight :
- lineHeight;
- dx = (lineFeed.dx !== undefined && typeof(lineFeed.dx) === 'number') ? lineFeed.dx : dx;
- }
- const chr = (textItem.text).split("");
- let temp = "";
- const row = [];
- //循环出几行文字组成数组
- for (let a = 0, len = chr.length; a < len; a++) {
- if (countTextLength(Context, {
- text: temp,
- size: textItem.size
- }) <= maxWidth && countTextLength(Context, {
- text: (temp + chr[a]),
- size: textItem.size
- }) <= maxWidth) {
- temp += chr[a];
- if (a == (chr.length - 1)) {
- row.push(temp);
- }
- } else {
- row.push(temp);
- temp = chr[a];
- }
- }
- _app.log('循环出的文本数组:' + JSON.stringify(row));
- //只显示几行 变量间距lineHeight 变量行数lineNum
- let allNum = (lineNum >= 0 && lineNum < row.length) ? lineNum : row.length;
- for (let i = 0; i < allNum; i++) {
- let str = row[i];
- if (i == (allNum - 1) && allNum < row.length) {
- str = str.substring(0, str.length - 1) + '...';
- }
- const obj = { ...textItem,
- text: str,
- dx: i === 0 ? textItem.dx : (dx >= 0 ? dx : textItem.dx),
- dy: textItem.dy + (i * lineHeight),
- textLength: countTextLength(Context, {
- text: str,
- size: textItem.size
- })
- };
- _app.log('重新组成的文本对象:' + JSON.stringify(obj));
- newArr.push(obj);
- }
- } else {
- newArr.push(textItem);
- }
- }
- }
- _app.log('绘制文本新数组:' + JSON.stringify(newArr));
- drawTexts(Context, newArr);
- }
- function setFont(textItem = {}) {
- if (textItem.font && typeof(textItem.font) === 'string') {
- _app.log(textItem.font)
- return textItem.font;
- } else {
- let fontStyle = 'normal';
- let fontVariant = 'normal';
- let fontWeight = 'normal';
- let fontSize = textItem.size || 10;
- let fontFamily = 'sans-serif';
- fontSize = Math.ceil(Number(fontSize));
- if (textItem.fontStyle && typeof(textItem.fontStyle) === 'string')
- fontStyle = textItem.fontStyle.trim();
- if (textItem.fontVariant && typeof(textItem.fontVariant) === 'string')
- fontVariant = textItem.fontVariant.trim();
- if (textItem.fontWeight && (typeof(textItem.fontWeight) === 'string' || typeof(textItem.fontWeight) === 'number'))
- fontWeight = textItem.fontWeight.trim();
- if (textItem.fontFamily && typeof(textItem.fontFamily) === 'string')
- fontFamily = textItem.fontFamily.trim();
- return fontStyle + ' ' +
- fontVariant + ' ' +
- fontWeight + ' ' +
- fontSize + 'px' + ' ' +
- fontFamily;
- }
- }
- function drawTexts(Context, texts) { // 绘制文本
- _app.log('准备绘制文本方法, texts:' + JSON.stringify(texts));
- if (texts && _app.isArray(texts)) {
- _app.log('准备绘制文本方法, 是数组');
- if (texts.length > 0) {
- for (let i = 0; i < texts.length; i++) {
- drawTextFn(Context, texts[i]);
- }
- }
- } else {
- _app.log('准备绘制文本方法, 不是数组');
- drawTextFn(Context, texts);
- }
- }
- function drawTextFn(Context, textItem) {
- _app.log('进入绘制文本方法, textItem:' + JSON.stringify(textItem));
- if (textItem && _app.isObject(textItem) && textItem.text) {
- Context.font = setFont(textItem);
- Context.setFillStyle(textItem.color);
- Context.setGlobalAlpha(textItem.alpha);
- Context.setTextAlign(textItem.textAlign);
- Context.setTextBaseline(textItem.textBaseline);
- if (!textItem.maxLine) {
- Context.fillText(textItem.text, textItem.dx, textItem.dy);
- } else {
- fillTextWrap(Context, textItem.text, textItem.dx, textItem.dy, textItem.width * 0.9, 48, textItem.size)
- }
- if (textItem.lineThrough && _app.isObject(textItem.lineThrough)) {
- _app.log('有删除线');
- let lineThrough = textItem.lineThrough;
- lineThrough.alpha = lineThrough.alpha !== undefined ? lineThrough.alpha : textItem.alpha;
- lineThrough.style = lineThrough.style || textItem.color;
- lineThrough.width = lineThrough.width !== undefined ? lineThrough.width : textItem.size / 10;
- lineThrough.cap = lineThrough.cap !== undefined ? lineThrough.cap : 'butt';
- _app.log('删除线对象:' + JSON.stringify(lineThrough));
- Context.setGlobalAlpha(lineThrough.alpha);
- Context.setStrokeStyle(lineThrough.style);
- Context.setLineWidth(lineThrough.width);
- Context.setLineCap(lineThrough.cap);
- let mx, my;
- switch (textItem.textAlign) {
- case 'left':
- mx = textItem.dx;
- break;
- case 'center':
- mx = textItem.dx - (textItem.textLength) / 2;
- break;
- default:
- mx = textItem.dx - (textItem.textLength);
- break;
- }
- switch (textItem.textBaseline) {
- case 'top':
- my = textItem.dy + (textItem.size * .5);
- break;
- case 'middle':
- my = textItem.dy;
- break;
- default:
- my = textItem.dy - (textItem.size * .5);
- break;
- }
- Context.beginPath();
- Context.moveTo(mx, my);
- Context.lineTo(mx + textItem.textLength, my);
- Context.stroke();
- Context.closePath();
- _app.log('删除线完毕');
- }
- Context.setGlobalAlpha(1);
- Context.font = '10px sans-serif';
- }
- }
- /**
- * 海报文字换行
- */
- function fillTextWrap(ctx, text, x, y, maxWidth, lineHeight, fontSize) {
- // 默认参数
- maxWidth = maxWidth
- lineHeight = lineHeight || 20
- // 校验参数
- if (
- typeof text !== 'string' ||
- typeof x !== 'number' ||
- typeof y !== 'number'
- ) {
- return
- }
- // 字符串分割为数组
- const arrText = text.split('')
- // 当前字符串及宽度
- let currentText = ''
- let currentWidth
- let index = 0
- for (let letter of arrText) {
- currentText += letter
- currentWidth = ctx.measureText(currentText).width
- currentWidth = currentWidth || measureText(currentText, ctx, fontSize)
- if ((currentWidth > maxWidth) && (index < 2)) {
- if (index === 1) {
- currentText = currentText.substring(0, currentText.length - 1)
- currentText += ' ...'
- }
- ctx.fillText(currentText, x, y)
- currentText = ''
- y += lineHeight
- index += 1;
- }
- }
- if (currentText && index < 2) {
- ctx.fillText(currentText, x, y)
- }
- }
- function measureText(text, canvas, fontSize)
- {
- var text = text.split('');
- var width = 0;
- for (let i = 0; i < text.length; i++)
- {
- let item = text[i];
- if (/[a-zA-Z]/.test(item))
- {
- width += 7;
- } else if (/[0-9]/.test(item))
- {
- width += 5.5;
- } else if (/\./.test(item))
- {
- width += 2.7;
- } else if (/-/.test(item))
- {
- width += 3.25;
- } else if (/[\u4e00-\u9fa5]/.test(item))
- {
- width += 10;
- } else if (/\(|\)/.test(item))
- {
- width += 3.73;
- } else if (/\s/.test(item))
- {
- width += 2.5;
- } else if (/%/.test(item))
- {
- width += 8;
- } else
- {
- width += 10;
- }
- }
- return width * fontSize / 10;
- }
- // export
- function drawImage(Context, images) { // 绘制图片
- _app.log('判断图片数据类型:' + JSON.stringify(images))
- if (images && _app.isArray(images)) {
- if (images.length > 0) {
- for (let i = 0; i < images.length; i++) {
- readyDrawImageFn(Context, images[i]);
- }
- }
- } else {
- readyDrawImageFn(Context, images);
- }
- }
- function readyDrawImageFn(Context, img) {
- _app.log('判断绘制图片形状, img:' + JSON.stringify(img));
- if (img.url) {
- if (img.circleSet) {
- drawCircleImage(Context, img);
- } else if (img.roundRectSet) {
- drawRoundRectImage(Context, img);
- } else {
- drawImageFn(Context, img);
- }
- }
- }
- function drawImageFn(Context, img) {
- _app.log('进入绘制默认图片方法, img:' + JSON.stringify(img));
- if (img.url) {
- const hasAlpha = !_app.isUndef(img.alpha);
- img.alpha = Number(!_app.isUndef(img.alpha) ? img.alpha : 1);
- Context.setGlobalAlpha(img.alpha);
- _app.log('绘制默认图片方法, 有url');
- if (img.dWidth && img.dHeight && img.sx && img.sy && img.sWidth && img.sHeight) {
- _app.log('绘制默认图片方法, 绘制第一种方案');
- Context.drawImage(img.url, Number(img.dx || 0), Number(img.dy || 0),
- Number(img.dWidth) || false, Number(img.dHeight) || false,
- Number(img.sx) || false, Number(img.sy) || false,
- Number(img.sWidth) || false, Number(img.sHeight) || false);
- } else if (img.dWidth && img.dHeight) {
- _app.log('绘制默认图片方法, 绘制第二种方案');
- Context.drawImage(img.url, Number(img.dx || 0), Number(img.dy || 0),
- Number(img.dWidth) || false, Number(img.dHeight) || false);
- } else {
- _app.log('绘制默认图片方法, 绘制第三种方案');
- Context.drawImage(img.url, Number(img.dx || 0), Number(img.dy || 0));
- }
- if (hasAlpha) {
- Context.setGlobalAlpha(1);
- }
- }
- _app.log('绘制默认图片方法, 绘制完毕');
- }
- function drawCircleImage(Context, obj) {
- _app.log('进入绘制圆形图片方法, obj:' + JSON.stringify(obj));
- let {
- dx,
- dy,
- dWidth,
- dHeight,
- circleSet,
- imageInfo
- } = obj;
- let x, y, r;
- if (typeof circleSet === 'object') {
- x = circleSet.x;
- y = circleSet.y;
- r = circleSet.r;
- }
- if (!r) {
- let d;
- d = dWidth > dHeight ? dHeight : dWidth;
- r = d / 2;
- }
- x = x ? dx + x : (dx || 0) + r;
- y = y ? dy + y : (dy || 0) + r;
- Context.save();
- Context.beginPath();
- Context.arc(x, y, r, 0, 2 * Math.PI, false);
- Context.closePath();
- Context.setGlobalAlpha(0);
- Context.fillStyle = '#FFFFFF';
- Context.fill();
- Context.setGlobalAlpha(1);
- Context.clip();
- drawImageFn(Context, obj);
- _app.log('默认图片绘制完毕');
- Context.restore();
- }
- function drawRoundRectImage(Context, obj) { // 绘制矩形
- _app.log('进入绘制矩形图片方法, obj:' + JSON.stringify(obj));
- Context.save();
- let {
- dx,
- dy,
- dWidth,
- dHeight,
- roundRectSet,
- imageInfo
- } = obj;
- let r;
- if (typeof roundRectSet === 'object') {
- r = roundRectSet.r;
- }
- r = r || dWidth * .1;
- if (dWidth < 2 * r) {
- r = dWidth / 2;
- }
- if (dHeight < 2 * r) {
- r = dHeight / 2;
- }
- Context.beginPath();
- Context.moveTo(dx + r, dy);
- Context.arcTo(dx + dWidth, dy, dx + dWidth, dy + dHeight, r);
- Context.arcTo(dx + dWidth, dy + dHeight, dx, dy + dHeight, r);
- Context.arcTo(dx, dy + dHeight, dx, dy, r);
- Context.arcTo(dx, dy, dx + dWidth, dy, r);
- Context.closePath();
- Context.setGlobalAlpha(0);
- Context.fillStyle = '#FFFFFF';
- Context.fill();
- Context.setGlobalAlpha(1);
- Context.clip();
- drawImageFn(Context, obj);
- Context.restore();
- _app.log('进入绘制矩形图片方法, 绘制完毕');
- }
- // export
- function drawQrCode(Context, qrCodeObj) { //生成二维码方法, 参考了 诗小柒 的二维码生成器代码
- _app.log('进入绘制二维码方法')
- _app.showLoading('正在生成二维码');
- let qrcodeAlgObjCache = [];
- let options = {
- text: String(qrCodeObj.text || '') || '', // 生成内容
- size: Number(qrCodeObj.size || 0) || 200, // 二维码大小
- background: String(qrCodeObj.background || '') || '#ffffff', // 背景色
- foreground: String(qrCodeObj.foreground || '') || '#000000', // 前景色
- pdground: String(qrCodeObj.pdground || '') || '#000000', // 定位角点颜色
- correctLevel: Number(qrCodeObj.correctLevel || 0) || 3, // 容错级别
- image: String(qrCodeObj.image || '') || '', // 二维码图标
- imageSize: Number(qrCodeObj.imageSize || 0) || 40, // 二维码图标大小
- dx: Number(qrCodeObj.dx || 0) || 0, // x轴距离
- dy: Number(qrCodeObj.dy || 0) || 0 // y轴距离
- }
- let qrCodeAlg = null;
- let d = 0;
- for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
- d = i;
- if (qrcodeAlgObjCache[i].text == options.text && qrcodeAlgObjCache[i].text.correctLevel == options.correctLevel) {
- qrCodeAlg = qrcodeAlgObjCache[i].obj;
- break;
- }
- }
- if (d == l) {
- qrCodeAlg = new QRCodeAlg(options.text, options.correctLevel);
- qrcodeAlgObjCache.push({
- text: options.text,
- correctLevel: options.correctLevel,
- obj: qrCodeAlg
- });
- }
- let getForeGround = function(config) {
- let options = config.options;
- if (options.pdground && (
- (config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
- (config.row > (config.count - 6) && config.row < (config.count - 2) && config.col > 1 && config.col < 5) ||
- (config.row > 1 && config.row < 5 && config.col > (config.count - 6) && config.col < (config.count - 2))
- )) {
- return options.pdground;
- }
- return options.foreground;
- }
- let count = qrCodeAlg.getModuleCount();
- let ratioSize = options.size;
- let ratioImgSize = options.imageSize;
- //计算每个点的长宽
- let tileW = (ratioSize / count).toPrecision(4);
- let tileH = (ratioSize / count).toPrecision(4);
- //绘制
- for (let row = 0; row < count; row++) {
- for (let col = 0; col < count; col++) {
- let w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW));
- let h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW));
- let foreground = getForeGround({
- row: row,
- col: col,
- count: count,
- options: options
- });
- Context.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background);
- Context.fillRect(options.dx + Math.round(col * tileW), options.dy + Math.round(row * tileH), w, h);
- }
- }
- if (options.image) {
- let x = options.dx + Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
- let y = options.dy + Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
- drawRoundedRect(Context, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
- Context.drawImage(options.image, x, y, ratioImgSize, ratioImgSize);
- // 画圆角矩形
- function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
- ctxi.setLineWidth(lineWidth);
- ctxi.setFillStyle(options.background);
- ctxi.setStrokeStyle(options.background);
- ctxi.beginPath(); // draw top and top right corner
- ctxi.moveTo(x + r, y);
- ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner
- ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner
- ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner
- ctxi.arcTo(x, y, x + r, y, r);
- ctxi.closePath();
- if (fill) {
- ctxi.fill();
- }
- if (stroke) {
- ctxi.stroke();
- }
- }
- }
- _app.log('进入绘制二维码方法完毕')
- _app.hideLoading();
- }
- function getShreUserPosterBackground(objs) { //检查背景图是否存在于本地, 若存在直接返回, 否则调用getShreUserPosterBackgroundFc方法
- let {
- backgroundImage,
- type
- } = objs;
- return new Promise(async (resolve, reject) => {
- try {
- _app.showLoading('正在获取海报背景图');
- const savedFilePath = await getShreUserPosterBackgroundFc(objs)
- _app.hideLoading();
- resolve(savedFilePath);
- } catch (e) {
- _app.hideLoading();
- _app.showToast('获取分享用户背景图失败:' + JSON.stringify(e));
- _app.log(JSON.stringify(e));
- reject(e);
- }
- })
- }
- function getPosterStorage(type) {
- return _app.getStorageSync(getStorageKey(type));
- }
- function removePosterStorage(type) {
- const ShreUserPosterBackgroundKey = getStorageKey(type);
- const pbg = _app.getStorageSync(ShreUserPosterBackgroundKey);
- if (pbg && pbg.path) {
- _app.removeStorageSync(ShreUserPosterBackgroundKey);
- }
- }
- function setPosterStorage(type, data) {
- _app.setStorage(getStorageKey(type), data);
- }
- function getStorageKey(type) {
- return ShreUserPosterBackgroundKey + (type || 'default');
- }
- function getShreUserPosterBackgroundFc(objs, upimage) { //下载并保存背景图方法
- let {
- backgroundImage,
- type
- } = objs;
- _app.log('获取分享背景图, 尝试清空本地数据');
- return new Promise(async (resolve, reject) => {
- try {
- _app.showLoading('正在下载海报背景图');
- if (upimage) {
- _app.log('有从后端获取的背景图片路径');
- _app.log('尝试下载并保存背景图');
- const name = _app.fileNameInPath(upimage);
- const savedFilePath = await _app.downLoadAndSaveFile_PromiseFc(upimage);
- if (savedFilePath) {
- _app.log('下载并保存背景图成功:' + savedFilePath);
- const imageObj = await _app.getImageInfo_PromiseFc(savedFilePath);
- const returnObj = {
- path: savedFilePath,
- width: imageObj.width,
- height: imageObj.height,
- name
- }
- // #ifndef H5
- setPosterStorage(type, { ...returnObj
- });
- // #endif
- _app.hideLoading();
- resolve(returnObj);
- } else {
- _app.hideLoading();
- reject('not find savedFilePath');
- }
- } else {
- _app.log('没有从后端获取的背景图片路径, 尝试从后端获取背景图片路径');
- const image = await _app.getPosterUrl(objs);
- _app.log('尝试下载并保存背景图:' + image);
- const savedFilePath = await _app.downLoadAndSaveFile_PromiseFc(image);
- if (savedFilePath) {
- _app.log('下载并保存背景图成功:' + savedFilePath);
- const imageObj = await _app.getImageInfo_PromiseFc(savedFilePath);
- _app.log('获取图片信息成功');
- const returnObj = {
- path: savedFilePath,
- width: imageObj.width,
- height: imageObj.height,
- name: _app.fileNameInPath(image)
- }
- _app.log('拼接背景图信息对象成功:' + JSON.stringify(returnObj));
- // #ifndef H5
- setPosterStorage(type, { ...returnObj
- });
- // #endif
- _app.hideLoading();
- _app.log('返回背景图信息对象');
- resolve({ ...returnObj
- });
- } else {
- _app.hideLoading();
- reject('not find savedFilePath');
- }
- }
- } catch (e) {
- //TODO handle the exception
- reject(e);
- }
- });
- }
- module.exports = {
- getSharePoster,
- setText,
- setImage,
- drawText,
- drawImage,
- drawQrCode
- }
|