【移动端】vue宣传海报拼接二维码

  • 来源需求
    项目宣传海报,海报上有项目入口二维码,由于该海报的二维码是实时生成,因此不能用固定的二维码,所以才需要调用后端接口获取到对应的链接,然后转成二维码,最后拼接到海报图上,再进行展示。
  • 功能实现
    1、由于项目使用的是vue3框架,所以采用qrcode插件将链接转成二维码。文档地址
    2、拼接方式则是通过canvas将上一步生成好的二维码按照指定位置绘至海报图上。canvas文档
    3、通过json文件配置海报图和二维码位置。
    4、支持区分海报类型。(需要在代码中约定好类型枚举值)
    5、支持生成多张,使用van-swipe进行滑动切换海报。
  • 具体代码
// 模板
<div class="banner" id="banner">
    <van-swipe @change="swipeChange" :loop="false" :initial-swipe="bannerIndex">
        <van-swipe-item v-for="(img, index) in posterImage" :key="index">
            <img :src="img" />
        </van-swipe-item>
    </van-swipe>
</div>
// 逻辑
const route = useRoute()
const productType = route.query.posterType|| '' // 海报类型
const bannerIndex = ref(0)
const posterImage = ref([])
const swipe = ref(null)

// 监听轮播图
const swipeChange = index => {
    bannerIndex.value = index
}

// 核心方法
const canvasPoster = (imgList, code) => {
    const images = []
    const imagesOnload = []
    // 海报处理
    imgList.forEach((img, index) => {
        images[index] = new Image()
        images[index].setAttribute('crossOrigin', 'anonymous')
        images[index].src = img.url
        images[index].position = img.position
        imagesOnload[index] = new Promise((resolve, reject) => {
            images[index].onload = () => resolve()
            images[index].onerror = () => reject()
        })
    })
    // 二维码处理
    const invitationImg = new Image()
    invitationImg.src = code
    const invitationOnload = new Promise((resolve, reject) => {
        invitationImg.onload = () => resolve()
    })
    const resList = []
    return Promise.all([...imagesOnload, invitationOnload]).then(
        res => {
            images.forEach(img => {
                const canvas = document.createElement('canvas')
                canvas.width = img.width
                canvas.height = img.height
                const ctx = canvas.getContext('2d')
                ctx.rect(0, 0, canvas.width, canvas.height)
                ctx.fillStyle = '#fff'
                ctx.fill()
                ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
                ctx.fillRect(img.position[0], img.position[1], img.position[2], img.position[3])
                ctx.drawImage(invitationImg, img.position[0], img.position[1], img.position[2], img.position[3])
                const base64 = canvas.toDataURL('image/jpeg', 0.3)
                resList.push(base64)
            })
            return resList
        },
        err => {
            Toast.fail('海报生成失败')
        },
    )
}
// 页面初始化
onMounted(async () => {
    const data = {
        posterType,
    }
    // 请求配置json
    const posterListRes = await axios.get(
        `配置文件路径/配置文件.json?t=${+new Date()}`,
    )
    // 请求二维码链接
    apiService.getQrdoceUrl({ data }).then(res => {
        if (res.code === '0') {
            const { url } = res.data
            // 生成二维码
            QRCode.toDataURL(url, (err, qrCodeData) => {
                if (err) Toast.fail(err)
                const posterList = posterListRes.data
                canvasPoster(posterList[posterType], qrCodeData).then(imgList => {
                    posterImage.value = imgList
                })
            })
        }
    })
})
// json配置示例
{
  "type1": [
    {
      "url": "海报链接11",
      "position": [132, 536, 484, 484]
    }
    {
      "url": "海报链接12",
      "position": [132, 536, 484, 484]
    }
  ],
  "type1": [
    {
      "url": "海报链接21",
      "position": [570, 1152, 138, 138]
    }
    {
      "url": "海报链接22",
      "position": [570, 1152, 138, 138]
    }
  ],
  "desc": "注: 该字段并无实际意义,主要用来在配置时用来说明配置方法,防止忘记;type1: 海报类型1,type2: 海报类型2;position:[二维码左上角X坐标,二维码左上角Y坐标,二维码宽,二维码高]"
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值