背景:最近接到一个需求要在微信公众号h5动态生成海报长按进行下载。在各个浏览器是没问题的。去到微信公众号h5就不行了,百撕不得骑jie。后面发现是微信内置浏览器限制的原因。
需求:根据链接动态生成二维码,再结合背景图等标签生成海报,进行长按下载。
实现思路:
(1)uQRCode,uniapp生成二维码的工具。
<view v-show="!isComplete2Canvas" ref="scanRef" id="scan" class="scan">
<image src="@/static/img/xxx.png" class="scan_title" />
<view class="scan_user">
<view v-if="xxx" class="scan_user_box">
<image
:src="require(`@/static/img/${xxx}.png`)"
class="scan_user_img"
/>
</view>
<view class="scan_user_info">
<view class="scan_user_name">{{ xxx }}</view>
<view class="scan_user_phone">{{ xxx }}</view>
</view>
</view>
<view class="scan_qr">
<view class="scan_qr_title">xxxxxxxxxxx</view>
<view class="scan_qr_box">
<view class="scan_qr_code">
<uqrcode
ref="uqrcode"
canvas-id="qrcode"
:value="qrCodeValue"
:size="300"
sizeUnit="rpx"
:options="options"
@complete="completeQrCode($event)"
></uqrcode>
</view>
</view>
</view>
</view>
(2)使用html2canvas,将html生成图片,并生成临时路径
// 二维码生成后的回调
const completeQrCode = async () {
if(this.imgTempFilePath) return
const scanDom = document.querySelector('#scan')
const canvas = await html2canvas(scanDom, {
width: scanDom.clientWidth, //scanDom 原始宽度
height: scanDom.clientHeight,
scrollY: 0,
scrollX: 0,
useCORS: true // 解决文件跨域问题
})
const tempFilePath = canvas.toDataURL('image/png', 1)
this.imgTempFilePath = tempFilePath
this.isComplete2Canvas = true
return { success: true }
}
(3) 将图片的临时路径赋值给image标签,思路是将之前的html生成图片后进行隐藏,并赋值给image标签。
// 为了更好的交互,也可以加个loading,这样且换就不会太生硬,交互会好一些
<image v-show="isComplete2Canvas" :src="imgTempFilePath" class="scan_img" />
(4)最后就是利用浏览器,甚至是微信浏览器,图片默认的长按点击事件,这样即可以完成图片的下载,也可以让h5的图片直接分享给微信好友。注意不需要自己去写个uniapp的长按事件。
最后要实现点击下载的话,平常的浏览器的可以手写a标签实现,将临时文件赋值给a.href属性即可。微信公众号的浏览器的话会有限制,估计得引导用户点击打开系统浏览器进行下载。