123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- // 默认配置参数
- 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',
- ewmUrl: 'https://static.caimei365.com/app/mini-hehe/icon/icon-ewm-hehe.jpg',
- textArray: ['¥500.00¥300.00', '哈喽,赶快来参团吧!这件商品', '拼团买更便宜~'],
- scale: 0.5,
- })
- // 绘制海报
- 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.drawHeader()
- await this.drawCenterInfo()
- } catch (e) {
- console.log(e)
- reject(e)
- } finally {
- this.ctx.draw(true, res => {
- resolve(true)
- })
- }
- })
- }
- // 绘制海报头部(用户信息区域)
- async drawHeader() {
- try {
- const { avatarUrl, userName, scale, subTitle } = this.options
- const [error, result] = await uni.downloadFile({ url: avatarUrl })
- if (error) return
- // 绘制用户头像
- this.ctx.beginPath()
- this.ctx.arc(116 * scale, 108 * scale, 60 * scale, 0, 2 * Math.PI)
- this.ctx.setFillStyle('#fff')
- this.ctx.fill()
- this.ctx.clip()
- this.ctx.drawImage(result.tempFilePath, 56 * scale, 48 * scale, 120 * scale, 120 * scale)
- this.ctx.restore()
- // 绘制用户名和推荐语
- this.ctx.setFillStyle('#FFFFFF')
- this.ctx.font = 'bold 10px sans-serif'
- this.ctx.setFontSize(40 * scale)
- this.ctx.fillText(userName, 205 * scale, 96 * scale, 350 * scale)
- this.ctx.font = 'normal 10px sans-serif'
- this.ctx.setFontSize(26 * scale)
- this.ctx.fillText(subTitle, 205 * scale, 150 * scale, 350 * scale)
- this.ctx.save()
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- // 绘制背景
- 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, 1220 * scale)
- this.ctx.save()
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- // 绘制中心区域
- async drawCenterInfo() {
- try {
- const { scale } = this.options
- this.ctx.beginPath()
- this.ctx.rect(28 * scale, 214 * scale, 694 * scale, 978 * scale)
- this.ctx.setFillStyle('#FFFFFF')
- this.ctx.fill()
- this.ctx.clip()
- 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, 242 * scale, 638 * scale, 638 * scale)
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- // 绘制底部
- 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')
- if (txt && index === 0) {
- this.drawPrice(txt)
- } else {
- this.ctx.fillText(txt, 70 * scale, (980 + 56 * index) * scale)
- }
- })
- }
- }
- drawPrice(txt) {
- const { scale } = this.options
- const txts = (txt.startsWith('¥') ? txt.slice(1) : txt).split('¥')
- let txtLeft = 60 * scale
- txts.forEach((priceText, index) => {
- if (index === 0) {
- this.ctx.setFillStyle('#FF457B')
- this.ctx.setFontSize(24 * scale)
- this.ctx.fillText('¥', txtLeft, 954 * scale)
- const m1 = this.ctx.measureText('¥')
- this.ctx.setFontSize(40 * scale)
- this.ctx.fillText(priceText, txtLeft + m1.width, 954 * scale)
- const m2 = this.ctx.measureText(priceText)
- txtLeft = txtLeft + m1.width + m2.width + 8
- } else {
- this.ctx.setFillStyle('#999')
- this.ctx.setFontSize(24 * scale)
- this.ctx.fillText('¥' + priceText, txtLeft, 954 * scale)
- let m = this.ctx.measureText('¥' + priceText)
- this.ctx.fillRect(txtLeft, 946 * scale, m.width + 4, 1)
- }
- })
- }
- // 绘制底部二维码
- 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, 976 * scale, 160 * scale, 160 * scale)
- return Promise.resolve(true)
- } catch (e) {
- return Promise.reject(e)
- }
- }
- }
|