// 默认配置参数 const defaultOptions = () => ({ avatarUrl: 'https://static.caimei365.com/app/mini-hehe/icon/icon-join-us.png', userName: '采美', subTitle: '强烈为你推荐该商城', coverUrl: 'https://static.caimei365.com/app/mini-hehe/icon/icon-share.png', bgImageUrl: 'https://static.caimei365.com/app/mini-hehe/icon/bg-share-01.png', userBg: 'https://static.caimei365.com/app/img/icon/bg-card.png', userTitleBg: 'https://static.caimei365.com/app/img/icon/logo-fanbai.png', ewmUrl: 'https://static.caimei365.com/app/mini-hehe/icon/icon-ewm-hehe.jpg', textArray: [], scale: 0.5, }) // 绘制海报 export default class DrawPoster { constructor(ctx, options = {}) { this.ctx = ctx this.options = Object.assign(defaultOptions(), options) console.log('配置信息为:', this.options) } // 开始绘制 draw() { return new Promise(async (resolve, reject) => { try { await this.drawBgImage() // await this.drawHeader() await this.drawUserCoverImage() await this.drawCenterInfo() } catch (e) { console.log(e) reject(e) } finally { this.ctx.draw(true, res => { resolve(true) }) } }) } // 绘制背景 async drawBgImage() { try { const { bgImageUrl, scale } = this.options const [error, result] = await uni.downloadFile({ url: bgImageUrl }) if (error) return this.ctx.setFillStyle('#999999') this.ctx.save() return Promise.resolve(true) } catch (e) { return Promise.reject(e) } } // 绘制圆角矩形 async drawRoundRect(x, y, w, h, r) { this.ctx.beginPath() this.ctx.moveTo(x + r , y) this.ctx.arcTo(x + w, y, x + w, y + h, r) this.ctx.arcTo(x + w, y + h, x , y + h, r) this.ctx.arcTo(x, y + h, x, y, r) this.ctx.arcTo(x, y, x + w, y , r) this.ctx.setFillStyle('#FFFFFF') this.ctx.fill() this.ctx.clip() } // 绘制中心区域 async drawCenterInfo() { try { const { scale } = this.options this.ctx.beginPath() this.drawRoundRect(28 * scale, 28 * scale, 694 * scale, 878 * scale, 8) await this.drawCoverImage() await this.drawFooterText() await this.drawEwmImage() return Promise.resolve(true) } catch (e) { return Promise.reject(e) } } // 绘制封面图片 async drawCoverImage() { try { const { coverUrl, scale } = this.options const [error, result] = await uni.downloadFile({ url: coverUrl }) if (error) return this.ctx.drawImage(result.tempFilePath, 56 * scale, 56 * scale, 638 * scale, 658 * scale) return Promise.resolve(true) } catch (e) { return Promise.reject(e) } } // 绘制名片封面 async drawUserCoverImage() { try { const { userBg, scale, image, qrCode, linkMan, contractMobile } = this.options await this.drawBorderReduisImage(userBg, 28 * scale, 920 * scale, 694 * scale, 290 * scale, 8) await this.drawUserCardInner() // 绘制名片内容 await this.drawCircleImg(image, 120 * scale, 1090 * scale, 30) //头像 this.drawFontText(40 * scale, 200 * scale, 1070 * scale, '#fff', linkMan, 'bold') this.drawFontText(30 * scale, 200 * scale, 1130 * scale, '#fff', contractMobile, '400') await this.drawBorderReduisImage(qrCode, 520 * scale, 1000 * scale, 170 * scale, 170 * scale, 8) return Promise.resolve(true) } catch (e) { return Promise.reject(e) } } async drawUserCardInner() { try { const { userTitleBg, scale } = this.options const [error, result] = await uni.downloadFile({ url: userTitleBg }) if (error) return this.ctx.drawImage(result.tempFilePath, 56 * scale, 940 * scale, 200 * scale, 70 * scale) return Promise.resolve(true) } catch (e) { return Promise.reject(e) } } async drawCircleImg(img, x, y, r) { const [error, result] = await uni.downloadFile({ url: img }) console.log('result', result, x, y, r) if (error) return this.ctx.save() this.ctx.beginPath() let size = 2 * r this.ctx.arc(x, y, r, 0, 2 * Math.PI) this.ctx.clip() this.ctx.drawImage(result.tempFilePath, x - r, y - r, size, size) console.log('x - r, y - r, size, size', x - r, y - r, size, size) this.ctx.restore() } async drawBorderReduisImage(imgUrl, bg_x, bg_y, bg_w, bg_h, bg_r) { const [error, result] = await uni.downloadFile({ url: imgUrl }) if (error) return this.ctx.save() this.ctx.beginPath() this.ctx.arc(bg_x + bg_r, bg_y + bg_r, bg_r, Math.PI, Math.PI*1.5) this.ctx.arc(bg_x + bg_w - bg_r, bg_y + bg_r, bg_r, Math.PI * 1.5, Math.PI * 2) this.ctx.arc(bg_x + bg_w - bg_r, bg_y + bg_h - bg_r, bg_r, 0, Math.PI * 0.5) this.ctx.arc(bg_x + bg_r, bg_y + bg_h - bg_r, bg_r, Math.PI * 0.5, Math.PI) this.ctx.clip() this.ctx.drawImage(result.tempFilePath, bg_x, bg_y, bg_w, bg_h) this.ctx.restore() } // 绘制文字 drawFontText(fontsize, x, y, color, text, bold) { this.ctx.beginPath() this.ctx.font = `${bold} ${fontsize}px sans-serif` this.ctx.setFillStyle(color) this.ctx.fillText(text, x, y) } // 绘制底部 drawFooterText(callback) { const { scale, textArray } = this.options if (callback) { callback({ scale, ctx: this.ctx, textArray }) } else { textArray.forEach((txt, index) => { this.ctx.setFontSize(30 * scale) this.ctx.setFillStyle('#333') this.ctx.fillText(txt, 56 * scale, (710 + 56 * index) * scale) }) } } // 绘制底部二维码 async drawEwmImage() { try { const { ewmUrl, scale } = this.options const [error, result] = await uni.downloadFile({ url: ewmUrl }) if (error) return this.ctx.drawImage(result.tempFilePath, 524 * scale, 720 * scale, 160 * scale, 160 * scale) return Promise.resolve(true) } catch (e) { return Promise.reject(e) } } }