canvas绘制带二维码的海报页
用组件总是有各种问题,索性研究一下原生canvas画法
先上代码
<template>
<view class="content">
<canvas canvas-id="qrcode" class="qrcode" style="width: 400rpx;height:400rpx;" />
<canvas canvas-id="myCanvas" v-show="canvasShow" id='sss'></canvas>
<image :src="base64" mode="scaleToFill" v-if="!canvasShow" class="immm"></image>
</view>
</template>
<script>
export default {
data() {
return {
qrcode: '',
sceneStr: '',
canvasShow: true,
header: '',
base64: '',
baseURL: '',
ewm: '',
bg_img: '', //线上图片
system_info: [], //系统信息
hh: '',
ww: ''
}
},
components: {
uQRCode
},
onLoad(option) {
this.system_info = uni.getSystemInfoSync(); //屏幕宽高
this.ww = this.system_info.windowWidth; //准确的宽高
this.hh = this.system_info.windowHeight;
//自己的图片地址,有即可,注意跨域问题
this.bg_img = 'https://img-cdn-qiniu.dcloud.net.cn/uploads/avatar/000/72/20/93_avatar_max.jpg'
this.ewm = 'https://img-cdn-qiniu.dcloud.net.cn/uploads/avatar/000/72/20/93_avatar_max.jpg'
this.getQRcode()
},
methods: {
async getQRcode() {
this.qrcode = await uQRCode.make({
canvasId: 'qrcode',
componentInstance: this,
//二维码内容
text: 'https://uniapp.dcloud.io/',
size: 160,
margin: 5,
backgroundColor: '#ffffff',
foregroundColor: '#000000',
//生成的图片类型
fileType: 'png',
errorCorrectLevel: uQRCode.errorCorrectLevel.H
})
// console.log(this.qrcode)
this.getImg()
},
getImg() {
var that = this;
//这里等promise执行,避免拿不到图片临时路径,只能绘制本地图片,所以要先下载,下载本地图片页不影响
const promise1 = new Promise((resolve, reject) => {
uni.downloadFile({
url: that.bg_img,
success: (res) => {
resolve(res)
},
fail(err) {
console.log(err)
}
})
});
//TODO 二维码图片获取接口使用返回图片类型接口直接获取
const promise2 = new Promise((resolve, reject) => {
uni.downloadFile({
url: that.ewm,
//根据需要看是否要配置
//header: {
// Authorization: this.header
//},
success: (res) => {
resolve(res)
}
})
});
Promise.all([promise1, promise2]).then((values) => {
this.make_canvas(values[0], values[1]);
});
},
make_canvas(img01, img02) {
// console.log('img02.tempFilePath')
img02.tempFilePath = this.qrcode
const query = uni.createSelectorQuery().in(this);
var system_info = this.system_info;
let ww = system_info.windowWidth; //准确的宽高
let hh = system_info.windowHeight;
console.log(system_info);
var ctx = uni.createCanvasContext('myCanvas') //绑定画布
//根据图片比例来绘制图片,按实际情况填写
ctx.drawImage(img01.tempFilePath, 0, 0,ww,ww*2.1); //填充进图片
ctx.drawImage(img02.tempFilePath, 196/280*ww,510/614*ww*2.1, 80, 80); //填充进图片
ctx.setFillStyle('#000') //设置内容1的文字样式
ctx.setFontSize(30);
ctx.setTextAlign('center') //设置对于坐标点的对齐方式
ctx.setFillStyle("#FFFFFF") //设置内容2的文字样式
ctx.setFontSize(20);
ctx.setTextAlign('center') //同上
// ctx.fillText('海报案例',ww/2,hh/3+150)
ctx.draw(); //输出到画布中
uni.showLoading({ //增加loading等待效果
mask: true,
title: "海报生成中"
})
setTimeout(() => { //不加延迟的话,base64有时候会赋予undefined
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
this.base64 = res.tempFilePath
this.canvasShow = false
// console.log(this.base64)
}
})
uni.hideLoading();
}, 500)
},
bcFn() {
//uniapp不支持哦
uni.saveImageToPhotosAlbum({ //保存图片
filePath: this.base64,
success: (res) => {
uni.showToast({
title: '保存成功',
})
},
fail(r) {
uni.showToast({
title: '保存失败',
})
}
})
}
}
}
</script>
<style scoped>
#sss {
//canvas要显示出来才能画,所以把它放到看不到的地方,画二维码同理
position: absolute;
width: 100%;
height: 1624rpx;
top: -99999999rpx;
left: -99999999rpx;
z-index: 1;
/* background-color: #18B566; */
}
.immm {
position: relative;
width: 100%;
height: 1624rpx;
z-index: 100;
}
.qrcode {
position: absolute;
top: -999rpx;
left: -999rpx;
z-index: 1;
}
</style>
如果二维码内容多,记得放大一点,否则可能无法识别(二维码自己绘制,或者从接口拿都可以,看需求)。另外,一定不要把canvas和image标签放在一起,canvas是没有长按保存事件的,image才是要保存的图片
最后感谢提供二维码插件的大佬,十分感谢,非常好用插件地址
路漫漫其修远兮。。。