关于canvas合成分享图

2023-02-20,,

最近在uni-app项目中遇到一个合成分享图的需求,其实最开始是用原生写法来做的,后来发现在PC端测试是可以的,但在APP模拟器中会出现问题,可能是因为两者的js环境不同吧,uni-app官网也说了这两者不能等同

先来看看最开始写的原生方法

 // 获取下载链接
getDownloadLink() {
this.$axios
.get('/app/address')
.then(res => {
console.log(res)
this.downloadLink = res.data.data
// 转二维码
this.makeCode()
})
.catch(err => {
console.log(err);
});
},
// 链接转二维码
makeCode(){
let img = QR.createQrCodeImg(this.downloadLink,{'size':300});
this.downloadImg = img
console.log(img)
console.log(this.detailsData.banners[0]) },
// 商品分享图片合成
starDraw() {
let _that = this
let base64Img1 = 'data:image/gif;base64,'.concat(this.detailsData.bannersBase64[0])
console.log(base64Img1)
// console.log('data:image/gif;base64,'.concat(this.detailsData.bannersBase64[0]))
// return
var data = [base64Img1, this.downloadImg]
var base64 = []
var bigName = 'F.N次方'
var starName = this.detailsData.name
if(this.detailsData.lowestPrice === this.highestPrice){
var price = '¥' + this.detailsData.lowestPrice
}else{
var price = '¥' + this.detailsData.lowestPrice + '~' + this.detailsData.highestPrice }
console.log(this.detailsData.banners[0])
console.log(price)
var c = document.createElement('canvas'),
// var c = this.$refs.canvas
ctx = c.getContext('2d'),
len = data.length
c.width = 300
c.height = 450
ctx.rect(0, 0, 300, 300)
ctx.fillStyle = '#fff'
ctx.fill()
function drawing(n) {
if (n < len) {
var img = new Image
// img.setAttribute("crossOrigin",'Anonymous')
// img.crossOrigin = 'Anonymous'; //解决跨域
img.crossOrigin = 'Anonymous'
img.src = data[n]
img.onload = function () {
if (n == 1) {
ctx.fillRect(0, 300, 300, c.height-300)
ctx.fillStyle = '#fff'
ctx.drawImage(img, c.width-110, 330, 100, 100);
console.log(1)
ctx.font = '14px sans-serif'
ctx.textBaseline = 'top'
ctx.textAlign = 'start'
ctx.fillStyle = '#000'
ctx.fillText(bigName,10,320)
ctx.fillText(starName, 10, 340)
ctx.font = '14px sans-serif'
ctx.fillStyle = 'red'
ctx.fillText(price, 10, 380)
console.log(2)
} else {
ctx.drawImage(img, 0, 0, c.width, c.height)
}
drawing(n + 1);
}
} else {
//保存生成作品图片
base64.push(c.toDataURL());
_that.base64Data = base64[0]
console.log(_that.base64Data)
// fn();
}
}
drawing(0);
}

这种事原生写法,在浏览器中测试能通过,但APP中会出错

下面来看看使用uni-app的方法来解决的

 copyFn() {
let that = this
var goodsName = this.detailsData.name
var text = 'F.N'
if(this.detailsData.lowestPrice === this.highestPrice){
var price = '¥' + this.detailsData.lowestPrice
}else{
var price = '¥' + this.detailsData.lowestPrice + '~' + this.detailsData.highestPrice }
let ww, hh;
let base64Img1 = 'data:image/gif;base64,'.concat(this.detailsData.bannersBase64[0])
const query = uni.createSelectorQuery().in(this);
query.select('#sss').boundingClientRect(data => { //获取canvas-dom
ww = data.width; //准确的宽高
hh = 450
var ctx = uni.createCanvasContext('myCanvas') //绑定画布
ctx.drawImage(base64Img1, 0, 0, ww, 300); //填充进图片
// this.downloadImg
ctx.setFillStyle('#000') //设置内容1的文字样式
ctx.setFontSize(20);
ctx.rect(0, 300, ww, 300)
ctx.setFillStyle('#fff')
ctx.fill()
ctx.drawImage(that.downloadImg, 240, 360, 100, 100)
// ctx.setTextAlign('center')
ctx.setFillStyle('#000')
ctx.fillText(text,50,hh/2+120)
// ctx.setTextAlign('center')
ctx.fillText(goodsName,50,hh/2+150)
ctx.setFillStyle('red')
ctx.setFontSize(16);
ctx.fillText(price,50,hh/2+180)
ctx.draw(); //输出到画布中
uni.showLoading({ //增加loading等待效果
mask:true
})
setTimeout(()=>{ //不加延迟的话,有时候会赋予undefined
uni.canvasToTempFilePath({
canvasId:'myCanvas',
success: (res) => {
console.log(res.tempFilePath)
this.shareImage=res.tempFilePath
}
})
uni.hideLoading();
},3000)
}).exec(); }

这样就能解决APP中报错的问题,然后再通过调用uni-app分享接口将合成图分享出去

关于canvas合成分享图的相关教程结束。

《关于canvas合成分享图.doc》

下载本文的Word格式文档,以方便收藏与打印。