VUE微信H5生成二维码海报保存
不许动一二三 人气:1一、效果
二、说明
公司需求:宣传海报从后台获取,二维码地址也从后台获得,然后生成一个海报,海报上固定位置放二维码,长按图片可以保存在本地相册(其实前面的需求是点击按钮,下载海报图到本地相册,然后h5下载的实现原理是生成一个a标签链接,然后下载,在电脑模拟器可以下载,在微信浏览器一点反应没有,所以退一步,长按保存),下面是使用版本,UI插件用的是vant(有赞)
- vue:“^2.6.11”,
- “html2canvas”: “1.4.1”,
- “vant”: “^2.8.1”,
- “vue_qrcodes”: “^1.1.3”
三、思路
从后端获取海报图,获取二维码链接,然后将二维码定位到图片固定位置,最后通过html2canvas生成canvas,然后通过canvas.toDataURL(“image/png”)生成
四、效果
从第三张图就可以看到长按保存的就是带有二维码的海报图了
五、代码实现
实现的原理就是:先把二维码定位到海报图上,然后通过html2canvas生成带二维码的海报,最后用这个图片覆盖在imageWrapper1元素上,才能下载到带二维码的海报图,这也是为什么要等待框显示正在生成海报图。
<template> <!--子组件--> <div class="posterpopup"> <van-popup v-model="popupVisible" @closed="closePopup"> <div id="imageWrapper1"> <img class="posterpopup-img" :src="popupObj.posterurl || popupObj.photourl" /> <div class="qrcode1" ref="qrcode" id="imageWrapper"> <qrcode :url="qrUrl" colorDark="#000" colorLight="#fff" :wid="wid" :hei="wid" :imgwid="imgwid" :imghei="imgwid" ></qrcode> </div> </div> <div class="posterpopup-img1" v-if="posterUrl"> <img :src="posterUrl" id="posterUrl" /> </div> <div class="posterpopup-wrap"> <img src="@/assets/image/download.png" alt="" /> <div class="wrap-text">长按保存图片</div> </div> </van-popup> </div> </template> <script> import qrcode from "vue_qrcodes"; import html2canvas from "html2canvas"; export default { name: "PosterPopup", props: { popupVisible: false, popupObj: { type: Object, default: {}, }, qrUrl: "", }, components: { qrcode, }, data() { return { imgwid: 30, // 二维码logo宽度 wid: 80, // 二维码宽度 wrapWid: 80, // 外边框宽度 posterUrl: "", controllShow: true, }; }, methods: { closePopup() { this.posterUrl = '' this.$emit("closePopup"); }, toSaveImage() { // 保存图片 this.$nextTick(async () => { var imageWrapper = document.getElementById("imageWrapper1"); try { let canvas = await html2canvas(imageWrapper, { height: imageWrapper.offsetHeight, width: imageWrapper.offsetWidth, backgroundColor: null, useCORS: true, allowTaint: true, scrollX: 0, scrollY: 0, dpi: window.devicePixelRatio * 2, // dpi: 300 }); this.controllShow = false; this.posterUrl = canvas.toDataURL("image/png"); this.$Toast.clear(); } catch (err) {} }); }, dataURLToBlob(dataurl) { let arr = dataurl.split(","); let mime = arr[0].match(/:(.*?);/)[1]; let bstr = atob(arr[1]); let n = bstr.length; let u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }, }, watch: { popupVisible(newVal, oldVal) { if (newVal) { this.$Toast.loading({ message: "海报生成中,请稍等", duration: 0, className: "zIndex", }); this.$nextTick(() => { this.toSaveImage(); }); } else { this.controllShow = true; this.$Toast.clear(); } }, }, }; </script> <style lang="scss" scoped> .posterpopup { .van-popup { background-color: transparent; overflow-y: hidden; width: 568px; height: 90vh; } #imageWrapper1 { position: absolute; min-width: 568px; min-height: 990px; } .posterpopup-img { width: 568px; height: 100%; } .posterpopup-img1 { width: 568px; height: 990px; & img { width: 100%; height: 13.2rem; } } .posterpopup-wrap { position: absolute; width: 302px; height: 70px; bottom: 50px; left: 50%; transform: translateX(-50%); // margin-top: 100px; margin: 39px auto 0; & > img { width: 100%; height: 100%; } .wrap-text { position: absolute; top: 50%; transform: translateY(-50%); right: 30px; font-size: 30px; color: #fff; } } #imageWrapper { position: absolute; right: 30px; bottom: 35px; } #posterUrl { position: absolute; z-index: 2002; top: 0; left: 0; right: 0; bottom: 90px; margin: 0 auto; width: 568px; } } </style>
<!----> <posterPopup :popupVisible="popupVisible" :popupObj="popupObj" @closePopup="closePopup" :qrUrl="qrUrl"></posterPopup>
六、遇到的问题
1.如果你把海报放到云上(腾讯云,阿里云,七牛云),就是放在CDN上,那么云一定要设置以下的头文件,如果你不设置这个头文件,就有跨域问题,你就一直会生成不成功,实用html2canvas的话只能生成一个空白背景的二维码,这个搞了好久,采用了放在服务器本地,但是服务器本地图片下载又慢,影响体验,搞了几天,才知道一定要设置!!!
加载全部内容