vue使用qrcodejs2生成二维码且底部带文字描述,支持下载(日常记录)

发布时间 2023-05-31 15:00:08作者: 酸菜鱼没有鱼

使用qrcodejs2生成二维码的方法:

/**
 * 二维码生成
 * @param content 生成二维码内容
 * @param desc 二维码底部描述
 * @param qrcodeDom 挂在dom
 * @returns {*|HTMLDivElement}
 */
export function generatorQrcode (content, desc, qrcodeDom = null) {
  const qrcodeContent = qrcodeDom || document.createElement('div')
  qrcodeContent.width = '400px'
  qrcodeContent.height = '400px'
  const qrcodeCanvas = new QRCode(qrcodeContent, {
    text: content, // 需要转换为二维码的内容
    width: 300,
    height: 300,
    colorDark: '#000000',
    colorLight: '#ffffff',
    correctLevel: QRCode.CorrectLevel.H
  })
  var resolutionMultiple = 1 // 分辨率倍数
  var borderSize = 5 * resolutionMultiple // 边框留白
  var canvasWidth = 300 * resolutionMultiple // 图片宽度
  // 判断 参数为空的命名情况
  var text = desc || ''// 底部文字
  var fontSize = 16 * resolutionMultiple // 文字大小

  var canvasHeight = canvasWidth + fontSize * 5
  var canvas = document.createElement('canvas')
  if (!canvas.getContext) return
  canvas.width = canvasWidth
  canvas.height = canvasHeight

  var ctx = canvas.getContext('2d')
  ctx.fillStyle = 'rgb(255,255,255)' // 调色(纯白)
  ctx.fillRect(0, 0, canvasWidth, canvasHeight) // 绘制背景

  var qrcodeSize = canvasWidth - borderSize * 2
  ctx.drawImage(
    qrcodeContent.querySelector('canvas'),
    borderSize,
    borderSize,
    qrcodeSize,
    qrcodeSize
  ) // 填充二维码

  ctx.fill() // 填充背景

  ctx.fillStyle = 'rgb(0,0,0)' // 调色(纯黑)
  ctx.font = fontSize + 'px Arial' // 文本大小, 字体
  ctx.textAlign = 'center'
  //处理文字描述太长换行问题
  ctx = drawText(ctx, text, canvasWidth / 2, qrcodeSize + borderSize, qrcodeSize)
  // ctx.fillText(
  //   text,
  //   canvasWidth / 2,
  //   qrcodeSize + borderSize,
  //   qrcodeSize
  // ) // 绘制文本
  // 清除原二维码
  // qrcodeCanvas.clear()
  qrcodeContent.appendChild(canvas)
  Array.from(qrcodeContent.querySelectorAll('img')).forEach((item) => {
    // item.style.display = 'none'
    item.remove()
    // console.log('img', item)
  })
  return qrcodeContent
}

/**
 *  文字换行
 * canvas文本换行处理
 * @param ctx canvas的 2d 对象
 * @param desc 绘制的文字
 * @param x 文字X坐标
 * @param y 文字Y坐标
 * @param w 文字最大宽度
 * @param space 每行字体y坐标间隔默认17
 */
function drawText (ctx, desc, x, y, w, space = 17) {
  // ctx:canvas的 2d 对象,t:绘制的文字,x,y:文字坐标,w:文字最大宽度
  const chr = desc
  let temp = ''
  const row = []

  for (let a = 0; a < chr.length; a++) {
    if (ctx.measureText(temp).width < w && ctx.measureText(temp + (chr[a])).width <= w) {
      temp += chr[a]
    } else {
      row.push(temp)
      temp = chr[a]
    }
  }
   row.push(temp)
  for (let b = 0; b < row.length; b++) {
    ctx.fillText(row[b], x, y + (b + 1) * space)// 每行字体y坐标间隔20
  }
  return ctx
}

使用: 只需要传二维码内容,底部文字描述和dom节点即可

//节点
<div id="qrcode" ref="qrCodeUrl"></div>

//使用生成二维码
this.qrcode = generatorQrcode(contentText, desc, this.$refs.qrCodeUrl)

 

下载:

download () {
  const a = document.createElement('a')
  //获取二维码画布,实质是canvas节点
  a.href = this.$refs.qrCodeUrl.children[1].toDataURL('image/png', 0.5)
  a.download = this.qrDesc + '.png'
  a.click()
},