vue生成二维码图片+文字说明

需求:点击下载图片,上方是二维码,下方显示该二维码的相关内容,并且居中显示,支持换行

解决方案步骤:

  1. 使用qrcode生成二维码的DataURL。

  2. 创建canvas,将二维码图片绘制到canvas的上半部分。

  3. 在canvas的下半部分绘制文字,处理换行和样式。

  4. 将canvas转换为图片,触发下载。

具体实现步骤:

1、安装依赖

复制代码
npm install qrcode --save

2、组件实现

复制代码
<template>
  <div>
    <button @click="generateAndDownload">下载图片</button>
    <canvas ref="canvas" style="display: none;"></canvas>
  </div>
</template>

<script>
import QRCode from 'qrcode'

export default {
  data() {
    return {
      canvasWidth: 400,    // 画布宽度
      canvasHeight: 400,   // 画布高度
      qrSize: 300,        // 二维码尺寸
      textConfig: {        // 文字配置
        content: '这是图片的文字说明部分,支持自动换行功能,当文字超过宽度限制时会自动换行显示。',
        x: 40,
        y: 320,
        lineHeight: 24,
        maxWidth: 320,     // canvasWidth - 80
        fontSize: '16px Arial',
        color: 'black'
      }
    }
  },
  methods: {
    // 文字换行处理
    wrapText(ctx, text, x, y, maxWidth, lineHeight) {
      const chars = text.split('')
      let line = ''
      let testLine = ''

      // 设置精确文本测量基线
      ctx.textBaseline = 'top'
      let xCoord = x
      for (let i = 0; i < chars.length; i++) {
        testLine = line + chars[i]
        const metrics = ctx.measureText(testLine)

        if (metrics.width > maxWidth && i > 0) {
          ctx.fillText(line, x, y)
          line = chars[i]
          y += lineHeight
        } else {
          line = testLine
          // 居中显示文字
          xCoord = (maxWidth - metrics.width) / 2 + 40
        }
      }
      ctx.fillText(line, xCoord, y)
    },

    // 生成并下载图片
    async generateAndDownload() {
      const canvas = this.$refs.canvas
      if (!canvas) return
      
      // 初始化画布
      canvas.width = this.canvasWidth
      canvas.height = this.canvasHeight
      const ctx = canvas.getContext('2d')
      if (!ctx) return

      try {
        // 绘制背景
        ctx.fillStyle = 'white'
        ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight)

        // 生成二维码
        const qrDataURL = await QRCode.toDataURL('https://example.com', { width: this.qrSize })
        await new Promise(resolve => {
          const img = new Image()
          img.onload = () => {
            // 居中绘制二维码
            const margin = (this.canvasWidth - this.qrSize) / 2
            ctx.drawImage(img, margin, 20, this.qrSize, this.qrSize)
            resolve()
          }
          img.src = qrDataURL
        })

        // 绘制文字
        ctx.fillStyle = this.textConfig.color
        ctx.font = this.textConfig.fontSize
        this.wrapText(
          ctx,
          this.textConfig.content,
          this.textConfig.x,
          this.textConfig.y,
          this.textConfig.maxWidth,
          this.textConfig.lineHeight
        )

        // 触发下载
        const link = document.createElement('a')
        link.download = 'qr-with-text.png'
        link.href = canvas.toDataURL('image/png')
        link.click()
      } catch (error) {
        console.error('生成失败:', error)
      }
    }
  }
}
</script>
相关推荐
一 乐7 分钟前
海产品销售系统|海鲜商城购物|基于SprinBoot+vue的海鲜商城系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·后端
艾小码7 分钟前
还在死磕模板语法?Vue渲染函数+JSX让你开发效率翻倍!
前端·javascript·vue.js
炒毛豆8 分钟前
vue3 + antd + print-js 实现打印功能(含输出PDF)
前端·javascript·vue.js
天天向上10249 分钟前
el-table动态添加行,删除行
前端·javascript·vue.js
小王码农记1 小时前
vue2中实现天气预报
前端·javascript·vue.js·echarts
我命由我123451 小时前
Element Plus 组件库 - Select 选择器 value 为 index 时的一些问题
开发语言·前端·javascript·vue.js·html·ecmascript·js
一念一花一世界1 小时前
Arbess从初级到进阶(2) - 使用Arbess+GitLab实现Vue.js项目自动化部署
vue.js·ci/cd·gitlab·arbess
有趣的野鸭2 小时前
JAVA课程十一次实验课程主要知识点示例
java·前端·数据库
格鸰爱童话2 小时前
next.js(二)——从react到next.js
前端·javascript·react.js
西洼工作室6 小时前
项目环境变量配置全攻略
前端