最近刚接触小程序,碰到一个分享的功能,包括唯一的二维码,分享人头像,以及昵称
主要问题总结:
1.canvas 绘制的网络的图片必须先下载下来才能用
wx.downloadFile({
url: sharePicUrl, //图片路径
success(res) {
if (res.statusCode === 200) {
sharePicPath = res.tempFilePath
}
//qrCodeFilePath 二维码的路径 ,二维码是通过调用接口传递参数,后台生成返回的
this.drawShareImg(qrCodeFilePath, shareImgFilePath) //这个方法是用来拼接的生成图片
}
2.展示昵称的时候,可能碰到很长的名字需要换行,canvas 也不支持设置宽度 的属性,为了解决这个问题就四处百度,终于发现一个好用的:超过宽度可以...显示
//处理昵称的长度
textPrewrap(ctx, content, drawX, drawY, lineHeight, lineMaxWidth, lineNum) {
var drawTxt = ''; // 当前绘制的内容
var drawLine = 1; // 第几行开始绘制
var drawIndex = 0; // 当前绘制内容的索引
// 判断内容是否可以一行绘制完毕
if(ctx.measureText(content).width <= lineMaxWidth) {
ctx.fillText(content.substring(drawIndex, i), drawX, drawY);
} else {
for (var i = 0; i < content.length; i++) {
drawTxt += content[i];
if (ctx.measureText(drawTxt).width >= lineMaxWidth) {
if (drawLine >= lineNum) {
ctx.fillText(content.substring(drawIndex, i) + '..' , drawX, drawY);
break;
} else {
ctx.fillText(content.substring(drawIndex, i + 1) , drawX, drawY);
drawIndex = i + 1;
drawLine += 1;
drawY += lineHeight;
drawTxt = '';
}
} else {
// 内容绘制完毕,但是剩下的内容宽度不到lineMaxWidth
if (i === content.length - 1) {
ctx.fillText(content.substring(drawIndex) , drawX, drawY);
}
}
}
}
},
3.也是关于昵称的:一些特殊字符有的后台会做转义处理,展示的时候也要做同样的处理
类似如下:
/* 特殊字符替换*/
getChart (name) {
name = name.replace(/</g, '<');
name = name.replace(/>/g, '>');
name = name.replace(/ /g, "\t");
name = name.replace(/\n/g, "\r\n");
name = name.replace(/'/g, "'");
console.log("转义字符", name);
return name;
},
4.关于图片适配的问题
//获取手机屏幕宽
wx.getSystemInfo({
success: (res)=>{
this.setData({
screenWidth:res.screenWidth
})
}
});
//然后
const pxRate = 750 / this.data.screenWidth
const width = 750 //图片的宽
const height = 1361 //图片的高
let context = wx.createCanvasContext('firstCanvas', this)
//注意你的firstCanvas的样式也要 设置跟图片一样的宽高哟!
由于语言表达不太好,后面我把代码都贴出来,方便自己查找,太难了
//生成二维码图片
shareFriends: function () {
let that = this,
page = 'pages/activities/answerGame/game/game', //跳转路径
scene = encodeURIComponent( `shareId=${store.data.userInfo.custId}&activityCode=${config.activityCode.answerGame}&nickName=${store.data.userInfo.nickName}&avatar=${store.data.userInfo.avatarUrl}`
)
this.close()
showLoading('图片生成中')
const { query, activities } = App.$api
query(activities.getQRCodeImage, { //接口地址
urlMerge: `?page=${page}&scene=${scene}`,
}).then(
({ res = {} } = {}) => {
if (res.successful) {
that.setData({
isShowFriendShare: !that.data.isShowFriendShare,
})
//获取二维码路径
let fsm = wx.getFileSystemManager() //文件管理器
let FILE_BASE_NAME = 'share_product_qrCode' //自定义文件名
let buffer = wx.base64ToArrayBuffer(res.serializableData) //转为Buffer数据
let filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}` //二维码路径
fsm.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
that.generateShareImg(filePath)
},
fail() {
hideLoading()
toast('图片生成失败')
that.setData({
isShowMoments: true,
})
return
},
})
} else {
hideLoading()
toast('图片生成失败')
}
},
(error) => {
hideLoading()
toast('系统繁忙,请稍后再试')
}
)
},
//获取底图路径
generateShareImg(qrCodeFilePath) {
let that = this
let shareImgFilePath = ''
let shareImageUrl = that.data.imgurl
let sharePicPath = ''
let sharePicUrl = that.data.sharePic
wx.downloadFile({
url: shareImageUrl,
success(res) {
if (res.statusCode === 200) {
shareImgFilePath = res.tempFilePath
//获取测试结果图片
wx.downloadFile({
url: sharePicUrl,
success(res) {
if (res.statusCode === 200) {
sharePicPath = res.tempFilePath
that.setData({
sharePicPath:sharePicPath
})
}
that.drawShareImg(qrCodeFilePath, shareImgFilePath,sharePicPath)
}
})
} else {
hideLoading()
toast('系统繁忙,请稍后再试')
return
}
},
fail(res) {
hideLoading()
toast('系统繁忙,请稍后再试')
return
},
})
},
//拼接生成图片
drawShareImg(qrCodeFilePath, shareImgFilePath ,sharePicPath) {
let that = this
const pxRate = 750 / that.data.screenWidth
const width = 750
const height = 1361
let context = wx.createCanvasContext('firstCanvas', this)
context.beginPath()
console.log(width/pxRate, height/pxRate,'画布大小')
context.drawImage(shareImgFilePath, 0, 0, width/pxRate, height/pxRate)
hideLoading()
context.draw(true, () => {
context.drawImage(sharePicPath, 39 / pxRate, 223 / pxRate, 672 / pxRate, 815 / pxRate)
context.drawImage(qrCodeFilePath, 67 / pxRate, 1111/ pxRate, 200 / pxRate, 200 / pxRate)
context.setFontSize(14); //字号
context.setFillStyle('#ffffff'); //字体颜色
let nickName = that.getChart(that.data.nickName) //处理昵称
that.textPrewrap(context, nickName , 100/ pxRate, 320/ pxRate, 14,84, 1)
context.draw(true, () => {
that.uploadImageSave(pxRate,width,height)
})
})
},
//拼接生成图片
uploadImageSave(pxRate,width,height) {
let that = this
wx.canvasToTempFilePath(
{
x: 0,
y: 0,
width: width/pxRate,
height: height/pxRate,
destWidth: width,
destHeight: height,
canvasId: 'firstCanvas',
quality: 1,
success(res) {
hideLoading()
console.log('朋友圈分享图生成成功:' + res.tempFilePath)
that.setData({
imgSrc: res.tempFilePath,
isShowCanvas: false,
})
},
fail(err) {
hideLoading()
console.log('失败')
console.log(err)
},
},
)
},
/**
* 保存结果
*/
savePic () {
let that = this;
let imgDataUrl = that.data.imgSrc;
wx.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success(res) {
that.saveImg(imgDataUrl);
}
})
} else {
that.saveImg(imgDataUrl);
}
}
})
},
// 保存图片到系统相册
saveImg (imgDataUrl) {
let that = this
wx.getImageInfo({
src:imgDataUrl,
success: (res) => {
const { path } = res;
wx.saveImageToPhotosAlbum({
filePath: path,
success(res) {
wx.showToast({
title: '保存图片成功'
})
console.log("保存图片:success");
that.setData({
isShowFriendShare: false,
})
return;
},
fail(res) {
hideLoading()
console.log("保存图片:fail");
console.log(res);
}
})
}
})
},
网友评论