美文网首页
vue 用户信息生成分享海报

vue 用户信息生成分享海报

作者: DeadMoon | 来源:发表于2021-10-18 18:01 被阅读0次

    需要使用的地方: 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
    

    相关文章

      网友评论

          本文标题:vue 用户信息生成分享海报

          本文链接:https://www.haomeiwen.com/subject/vcmnoltx.html