需要使用的地方: new GeneratePoster({ qrUrl, companyName, userImg, userName, tips }).start()
const ERR_CODE_ENUM = {
CODE_ERROR: '加载二维码失败',
USER_IMG_ERROR: '加载头像失败'
}
const { clientWidth } = document.body
const DESIGN_WIDTH = 750
const SHANG = clientWidth / DESIGN_WIDTH
const CANVAS_SIZE = {
// eslint-disable-next-line no-mixed-operators
width: 670 * SHANG,
// eslint-disable-next-line no-mixed-operators
height: 750 * SHANG
}
// 用户头像
const USER_IMG = {
top: 20 * SHANG,
left: 20 * SHANG,
width: 100 * SHANG,
height: 100 * SHANG
}
const QR_IMG = {
top: 140 * SHANG,
left: 20 * SHANG,
width: 512 * SHANG,
height: 512 * SHANG
}
// 用户名字
const USER_NAME = {
size: 28 * SHANG,
top: 25 * SHANG,
left: 140 * SHANG,
color: '#333333'
}
// 企业名称
const COMPANT_NAME = {
size: 24 * SHANG,
top: 90 * SHANG,
left: 140 * SHANG,
color: 'rgba(51, 51, 51, 0.8)'
}
// 底部提示
const TIP_TEXT = {
size: 24 * SHANG,
top: 700 * SHANG,
left: 140 * SHANG,
color: '#000'
}
// eslint-disable-next-line no-unused-vars
class GeneratePoster {
constructor(param = {}) {
this.qrUrl = param.qrUrl
this.userName = param.userName || ''
this.userImg = param.userImg || ''
this.companyName = param.companyName || ''
this.tips = param.tips
}
async createCanvas() {
// eslint-disable-next-line func-names
const getPixelRatio = function (context) {
const backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1
return (window.devicePixelRatio || 1) / backingStore
}
const canvasEl = document.createElement('canvas')
const ctx = canvasEl.getContext('2d')
const ratio = getPixelRatio(ctx)
canvasEl.style.width = `${CANVAS_SIZE.width}px`
canvasEl.style.height = `${CANVAS_SIZE.height}px`
canvasEl.width = CANVAS_SIZE.width * ratio
canvasEl.height = CANVAS_SIZE.height * ratio
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvasEl.width, canvasEl.height)
ctx.scale(ratio, ratio)
return { ctx, canvasEl }
}
/**
* @desc 客户二维码
* @param ctx
* @private
*/
_drawQrCode(ctx) {
return new Promise((resolve, reject) => {
const imgEl = document.createElement('img')
imgEl.setAttribute('crossOrigin', 'Anonymous')
imgEl.src = this.qrUrl
imgEl.onload = () => {
ctx.drawImage(imgEl, (CANVAS_SIZE.width - QR_IMG.width) / 2, QR_IMG.top, QR_IMG.width, QR_IMG.height)
resolve()
}
imgEl.onerror = (err) => {
console.log(err)
reject(ERR_CODE_ENUM.CODE_ERROR)
}
})
}
/**
* 开始画二维码说明
* @param ctx
* @private
*/
async _drawTipsText(ctx) {
ctx.textBaseline = 'bottom'
ctx.font = `${TIP_TEXT.size}px bold`
ctx.fillStyle = TIP_TEXT.color
ctx.fillText(this.tips, TIP_TEXT.left, TIP_TEXT.top)
}
/**
* @desc 客户昵称
* @param ctx
* @private
*/
async _drawNickname(ctx) {
ctx.textBaseline = 'top'
ctx.font = `${USER_NAME.size}px bold`
ctx.fillStyle = USER_NAME.color
ctx.fillText(this.userName, USER_NAME.left, USER_NAME.top)
}
/**
* @desc 用户公司名称
* @param ctx
* @private
*/
_drawCompanyName(ctx) {
ctx.textBaseline = 'top'
ctx.font = `${COMPANT_NAME.size}px bold`
ctx.fillStyle = COMPANT_NAME.color
ctx.fillText(this.companyName, COMPANT_NAME.left, COMPANT_NAME.top)
}
/**
* 画用户头像
* @param ctx
* @private
*/
_drawUserImg(ctx) {
return new Promise((resolve, reject) => {
const imgEl = document.createElement('img')
imgEl.setAttribute('crossOrigin', 'Anonymous')
imgEl.src = this.userImg
imgEl.onload = function () {
ctx.drawImage(imgEl, USER_IMG.left, USER_IMG.top, USER_IMG.width, USER_IMG.height)
resolve()
}
imgEl.onerror = () => {
reject(ERR_CODE_ENUM.USER_IMG_ERROR)
}
})
}
async start() {
try {
const { ctx, canvasEl } = await this.createCanvas()
await this._drawUserImg(ctx)
await this._drawNickname(ctx)
await this._drawCompanyName(ctx)
await this._drawQrCode(ctx)
await this._drawTipsText(ctx)
return canvasEl.toDataURL('image/png')
} catch (e) {
console.error(e)
}
}
}
export default GeneratePoster
网友评论