故事的开始
事情是这样的,项目中需要一个页面,有一个全屏满铺的背景图,左下角展示一些用户信息,右下角展示通过某个 url 生成的二维码。如下:
遇到问题
开发技术栈是 Vue3 ,很快做完交付测试。在 android 手机上没有任何问题,而在 ios 手机的微信浏览器中长按时,大概率并不能识别到二维码,而是可以拖动背景图片、分享背景图片等。
解决
试错了一些解决方案,如img { -webkit-touch-callout: none !important; }、强制刷新等。最后想到笨方法,将整个 DOM 转换成图片展示。代码如下:
<template>
<div
class="relative text-16px min-h-100vh bg-#fff text-#fff"
ref="mainRef"
v-if="!mainImg"
>
<img :src="bgUrl" class="w-100vw" />
<div class="absolute top-640px left-30px">
用户信息
</div>
<div class="absolute top-590px right-30px">
<canvas ref="qrCodeRef" class="w-80px! h-80px!"></canvas>
<div class="text-center mt-5px text-12px">长按参与活动</div>
</div>
</div>
<div v-else>
<img :src="mainImg" alt="" class="w-100vw" />
</div>
</template>
<script setup lang="ts">
import html2canvas from 'html2canvas'
import QRCode from 'qrcode'
//创建 canvas 方法,放到 common utils 中
export const createBaseCanvas = (
scale: number,
width: number,
height: number
) => {
// 构造 canvas
const canvas = document.createElement('canvas')
canvas.width = width * scale
canvas.height = height * scale
const context = canvas.getContext('2d')
if (context) {
context.imageSmoothingEnabled = false
context.scale(scale, scale)
}
return canvas
}
const mainRef = ref()
const mainImg = ref()
// html to canvas
onMounted(() => {
setTimeout(() => {
const width = mainRef.value.offsetWidth
const height = mainRef.value.offsetHeight
const scale = window.devicePixelRatio
const canvas = createBaseCanvas(scale, width, height)
html2canvas(mainRef.value, {
useCORS: true,
scrollY: 0,
scrollX: 0,
width,
height,
logging: false,
scale: 1,
canvas
}).then((canvas: any) => {
try {
mainImg.value = canvas.toDataURL('image/png')
} catch (err) {
console.log(err)
}
})
})
})
// 二维码生成
const qrCodeRef = ref()
onMounted(() => {
QRCode.toCanvas(
qrCodeRef.value,
`${window.origin}/test`,
(error) => {
if (error) console.error(error)
}
)
})
const bgUrl = ref('https://cn.bing.com/images/search?view=detailV2&ccid=nFHrgJLw&id=1C6CFB20DA6F79811343267FF9E2E09CF7848EAD&thid=OIP.nFHrgJLwPjkJyZ7FIf5lVgHaFQ&mediaurl=https%3a%2f%2fimg.haote.com%2fupload%2fpic%2fimage%2f20190327%2f20190327172547_54242.png&exph=535&expw=754&q=%e8%94%a1%e5%be%90%e5%9d%a4%e6%89%93%e7%af%ae%e7%90%83%e5%9b%be%e7%89%87&simid=608021607027395562&FORM=IRPRST&ck=E80686FAA1AF81CB66543EFB6E00864F&selectedIndex=0&idpp=overlayview&ajaxhist=0&ajaxserp=0')
</script>
结尾
当下就想到这个解决办法了,如果有更好的解决办法,恳请评论区指教,感谢!