123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- // 默认配置参数
- const defaultOptions = () => ({
- avatarUrl: '',
- userName: '采美',
- subTitle: '强烈为你推荐该商城',
- coverUrl: '',
- bgImageUrl: 'https://static.caimei365.com/app/img/icon/bgImage.png',
- // userBg: 'https://static.caimei365.com/app/img/icon/bg-card.png',
- userBg: 'https://static.caimei365.com/app/img/bg/home_cumres_bg@2x.png',
- userTitleBg: 'https://static.caimei365.com/app/img/icon/logo-fanbai@2x.png',
- // userTitleBg: 'https://static.caimei365.com/app/img/icon/logo-fanbai.png',
- ewmUrl: '',
- textArray: [],
- scale: 0.5,
- duty: {
- text: '客户经理',
- bgColor: '#FFF1EB',
- color: '#fff'
- }
- })
- // 绘制海报
- export default class DrawPoster {
- constructor(ctx, options = {}) {
- this.ctx = ctx
- this.options = Object.assign(defaultOptions(), options)
- }
- // 开始绘制
- draw() {
- return new Promise(async (resolve, reject) => {
- try {
- await this.drawBgImage()
- 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.drawImage(result.tempFilePath, 0, 0, 750 * scale, 1240 * scale)
- this.ctx.save()
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- // 绘制圆角矩形
- drawRoundRect(x, y, w, h, r, color) {
- this.ctx.save()
- 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(color)
- this.ctx.fill()
- // this.ctx.clip()
- }
- // 绘制中心区域
- async drawCenterInfo() {
- try {
- const { scale, coverUrl, ewmUrl } = this.options
- this.ctx.beginPath()
- await this.drawRoundRect(28 * scale, 28 * scale, 694 * scale, 878 * scale, 8, '#FFFFFF')
- await this.drawFooterText()
- this.ctx.drawImage(coverUrl, 56 * scale, 56 * scale, 638 * scale, 658 * scale)
- this.ctx.drawImage(ewmUrl, 524 * scale, 730 * scale, 160 * scale, 160 * scale)
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- // 绘制封面图片
- async drawCoverImage() {
- try {
- this.ctx.beginPath()
- const { coverUrl, scale } = this.options
- this.ctx.drawImage(coverUrl, 56 * scale, 56 * scale, 638 * scale, 658 * scale)
- this.ctx.save()
- return Promise.resolve(true)
- } catch (e) {
- console.log(e)
- }
- }
- // 绘制名片封面
- async drawUserCoverImage() {
- try {
- const { userBg, scale, image, qrCode, linkMan, contractMobile, duty } = 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(36 * scale, 200 * scale, 1070 * scale, '#333333', linkMan, 'bold', true)
- this.drawFontText(30 * scale, 200 * scale, 1130 * scale, '#333333', contractMobile, '400')
- await this.drawBorderReduisImage(qrCode, 556 * scale, 1010 * scale, 120 * scale, 120 * scale, 6)
- this.drawFontText(18 * scale, 550 * scale, 1160 * scale, '#333333', ['长按或扫二维码', '——联系我——'], '400')
- 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 })
- 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)
- 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()
- }
- // 绘制文字
- async drawFontText(fontsize, x, y, color, text, bold, isDuty = false) {
- this.ctx.save()
- if (Array.isArray(text)) {
- this.ctx.beginPath()
- this.ctx.font = `${bold} ${fontsize}px sans-serif`
- this.ctx.setFillStyle(color)
- text.forEach((e, i) => {
- this.ctx.fillText(e, x, y + fontsize * i)
- })
- } else {
- this.ctx.beginPath()
- this.ctx.font = `${bold} ${fontsize}px sans-serif`
- this.ctx.setFillStyle(color)
- this.ctx.fillText(text, x, y)
- if (isDuty) {
- await this.drawRoundRect(x + (text.length * fontsize) + 8 , y-fontsize, 66, fontsize + 4, 4, '#FFF1EB')
- // this.ctx.fillStyle = `${this.options.duty.bgColor}`
- // this.ctx.fillRect(x + (text.length * fontsize) + 10, y-fontsize, 66, fontsize + 4)
- this.ctx.font = `${400} ${fontsize-6}px sans-serif`
- this.ctx.setFillStyle('#666666')
- this.ctx.fillText(this.options.duty.text, x + (text.length * fontsize) + 16, y - 2)
- }
- }
- }
- // 绘制底部
- drawFooterText(callback) {
- const { scale, textArray } = this.options
- this.ctx.beginPath()
- 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)
- })
- }
- this.ctx.save()
- }
- // 绘制底部二维码
- async drawEwmImage() {
- try {
- const { ewmUrl, scale } = this.options
- // const [error, result] = await uni.downloadFile({ url: ewmUrl })
- console.log(ewmUrl, this.options)
- // if (error) return
- this.ctx.drawImage(ewmUrl, 524 * scale, 730 * scale, 160 * scale, 160 * scale)
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- }
|