<template> <view class="main"> <view class="qrimg"> <tki-qrcode :cid="cid" ref="qrcode" :val="val" :size="size" :unit="unit" :background="background" :foreground="foreground" :pdground="pdground" :icon="icon" :iconSize="iconSize" :lv="lv" :onval="onval" :showLoading="showLoading" :loadMake="loadMake" :usingComponents="usingComponents" @result="qrR" /> </view> <canvas :style="{ width: '600rpx', height: '1066rpx',}" canvas-id="myCanvas" id="myCanvas" class="hb"></canvas> <view class="btm-btn" v-if="fina"> <!-- <view class="btn" @click="comfirm"> <image src="../../static/icon/fzlj.png" mode=""></image> <view class=""> 复制邀请链接 </view> </view> --> <view class="btn" @click="saveShareQrcode"> <image src="../../static/icon/fxhb.png" mode=""></image> <view class=""> 保存分享海报 </view> </view> </view> </view> </template> <script> import { mapState, mapMutations } from 'vuex'; import { getUserInfo } from '@/api/user.js'; var that export default { data() { return { cid: 'tki-qrcode-canvas', //canvasId,页面存在多个二维码组件时需设置不同的ID size:300, //生成的二维码大小 unit: 'upx', //大小单位尺寸 // show: true,//默认使用组件中的image标签显示二维码 val: '', //要生成的内容 background: '#ffffff', //二维码背景色 foreground: '#333333', //二维码前景色 pdground: '#333333', //二维码角标色 icon: '', //二维码图标URL(必须是本地图片,网络图需要先下载至本地) iconSize: 40, //二维码图标大小 lv: 3, //容错级别 onval: true, //监听val值变化自动重新生成二维码 loadMake: true, //组件初始化完成后自动生成二维码,val需要有值 usingComponents: false, //是否使用了自定义组件模式(主要是为了修复非自定义组件模式时 v-if 无法生成二维码的问题) showLoading: false, //是否显示loading erweimasrc: '', canvasW: 0, // 画布宽 canvasH: 0, // 画布高 SystemInfo: {}, // 设备信息 goodsImg: {}, // 商品主图 ewmImg: {}, // 二维码图片 ewmW: 0, // 二维码大小 title: '', // 商品标题 canvasShow: true, shareQrcodeUrl: '', //canvas本地路径 ratio: '', //画布比例 fina: false, } }, computed: { ...mapState(['baseURL', 'urlFile']), ...mapState('user', ['userInfo', 'orderInfo', 'hasLogin']) }, onLoad(options) { const obj = this; if (!this.userInfo.uid) { getUserInfo({}).then(e => { // 保存返回用户数据 obj.setUserInfo(e.data); //成功跳转首页 uni.switchTab({ url: '/pages/index/index' }); }); } else { this.val = this.baseURL + '/index/#/pages/public/index?spread=' + this.userInfo.uid } }, methods: { uniCopy(content) { /** * 小程序端 和 app端的复制逻辑 */ //#ifndef H5 uni.setClipboardData({ data: content, success: function() { console.log('success'); return true; } }); //#endif /** * H5端的复制逻辑 */ // #ifdef H5 if (!document.queryCommandSupported('copy')) { //为了兼容有些浏览器 queryCommandSupported 的判断 // 不支持 return false; } let textarea = document.createElement('textarea'); textarea.value = content; textarea.readOnly = 'readOnly'; document.body.appendChild(textarea); textarea.select(); // 选择对象 textarea.setSelectionRange(0, content.length); //核心 let result = document.execCommand('copy'); // 执行浏览器复制命令 textarea.remove(); return result; // #endif }, comfirm() { const result = this.uniCopy(this.val); if (result === false) { uni.showToast({ title: '不支持' }); } else { uni.showToast({ title: '复制成功', icon: 'none' }); } }, qrR(res) { this.erweimasrc = res console.log(res, 'erweima'); this.createPoster() }, async createPoster() { let that = this // 获取设备信息,主要获取宽度,赋值给canvasW 也就是宽度:100% this.SystemInfo = await this.getSystemInfo(); // 获取商品主图,二维码信息,APP端会返回图片的本地路径(H5端只能返回原路径) this.goodsImg = await this.getImageInfo('/static/img/sharebase.png'); this.ewmImg = await this.getImageInfo(this.erweimasrc); // this.canvasW = this.SystemInfo.windowWidth; // 画布宽度 this.ratio = this.SystemInfo.windowWidth / 750; this.canvasW = 600 * this.ratio; this.canvasH = 1066 * this.ratio; // #ifdef APP-PLUS this.ewmW = 350 * this.ratio; // #endif // #ifdef H5 this.ewmW = 250 * this.ratio; // #endif console.log(this.canvasH, 'this.canvasH') // this.canvasH = this.goodsImg.height + this.ewmW + 200; // 画布高度 = 主图高度+二维码高度 + 文字图片的间距(大概50) // 如果主图,二维码图片,设备信息都获取成功,开始绘制海报,这里需要用setTimeout延时绘制,否则可能会出现图片不显示。 if (this.goodsImg.errMsg == 'getImageInfo:ok' && this.ewmImg.errMsg == 'getImageInfo:ok' && this .SystemInfo.errMsg == 'getSystemInfo:ok') { console.log('ok') uni.showToast({ icon: 'loading', mask: true, duration: 10000, title: '海报绘制中', }); setTimeout(() => { var ctx = uni.createCanvasContext('myCanvas', this); // 填充背景色,白色 ctx.setFillStyle('#fff'); // 默认白色 ctx.fillRect(0, 0, this.canvasW, this.canvasH) // fillRect(x,y,宽度,高度) // 绘制商品主图,二维码 ctx.drawImage(this.goodsImg.path, 0, 0, this.canvasW, this .canvasH) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度) // #ifdef APP-PLUS ctx.drawImage(this.ewmImg.path, (this.canvasW / 2 - this.ewmW / 2),this.canvasH - 120*this.ratio - this.ewmW, this.ewmW, this.ewmW) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度,二维码的宽,高) // #endif // #ifdef H5 ctx.drawImage(this.ewmImg.path, (this.canvasW / 2 - this.ewmW / 2),this.canvasH - 170*this.ratio - this.ewmW, this.ewmW, this.ewmW) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度,二维码的宽,高) // #endif // 3、绘制商品标题,多余文字自动换行 ctx.setFontSize(24); // setFontSize() 设置字体字号 ctx.setFillStyle('#fff'); // setFillStyle() 设置字体颜色 ctx.textAlign = "center"; // 邀请码 ctx.fillText('邀请码:' + this.userInfo.uid,this.canvasW/2,this.canvasH -20) ctx.draw(false, (ret) => { // draw方法 把以上内容画到 canvas 中。 console.log(ret) uni.showToast({ icon: 'none', title: '生成成功!', }); that.fina = true uni.canvasToTempFilePath({ // 保存canvas为图片 canvasId: 'myCanvas', quality: 1, fileType: 'jpg', complete: function(res) { // 在H5平台下,tempFilePath 为 base64, // 图片提示跨域 H5保存base64失败,APP端正常输出临时路径 console.log(res) that.canvasShow = false that.shareQrcodeUrl = res.tempFilePath that.$forceUpdate() setTimeout(function() { console.log(that.shareQrcodeUrl, that .canvasShow) }, 2000) }, }) }); }, 1500) } else { console.log('err') } }, // 获取图片信息 getImageInfo(image) { return new Promise((req, rej) => { uni.getImageInfo({ src: image, success: function(res) { req(res) }, }); }) }, // 获取设备信息 getSystemInfo() { return new Promise((req, rej) => { uni.getSystemInfo({ success: function(res) { req(res) } }); }) }, //保存图片 saveShareQrcode() { console.log(this.shareQrcodeUrl) uni.saveImageToPhotosAlbum({ filePath: this.shareQrcodeUrl, success: (res) => { uni.showToast({ icon: 'none', position: 'bottom', title: "成功保存到相册", }); }, fail: (err) => { //重新提示用户打开保存图片的授权 if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") { uni.showModal({ title: '提示', content: '需要您授权保存相册', showCancel: false, success(res) { if (res.confirm) { uni.openSetting({ success(settingdata) { if (settingdata.authSetting[ 'scope.writePhotosAlbum']) { uni.showModal({ title: '提示', content: '获取权限成功,再次保存图片即可成功', showCancel: false, }) } else { uni.showModal({ title: '提示', content: '获取权限失败,无法保存到相册', showCancel: false }) } } }) } } }) } }, }) } } } </script> <style lang="scss"> .hb { margin: auto; } .qrimg { position: absolute; left: -9999rpx; top: -9999rpx; } button { height: 88upx; background-color: #feca00; color: #fff; border-radius: 44upx; text-align: center; line-height: 88upx; width: 60%; margin: 0 auto; margin-top: 30upx; } .btm-btn { position: fixed; bottom: 0; width: 750rpx; height: 200rpx; display: flex; background-color: #fff; border-radius: 20rpx 20rpx 0 0; justify-content: center; .btn { width: 50%; display: flex; flex-direction: column; justify-content: center; align-items: center; font-size: 26rpx; image { width: 66rpx; height: 66rpx; margin-bottom: 20rpx; } } } </style>