先上效果图
1、wxml
<button class="footer-item" bindtap="creatShareImageTap">分享</button>
<view class='share-mask' hidden="{{shareMask == false}}" catchtouchmove='true'></view>
<view class='canvas-box'>
<canvas canvas-id="goods-share" style='width:750rpx;height:1206rpx;position:fixed;left:9999px'></canvas>
</view>
2、wxss
.share-mask{
width: 100%;
height: 100%;
position: fixed;
z-index: 998;
left: 0;
top: 0;
background: #000;
opacity: 0.5;
}
.imagePathBox{
position: fixed;
top: 0;
right: 0;
bottom: 0;
z-index: 999;
width: 100%;
height: 100%;
/* width: 264px;
height: 376px; */
left:0;
/* margin-left:-132px; */
}
.shengcheng{
width: 70.4%;
height: 62.3%;
position: fixed;
top: 164rpx;
left: 50%;
margin-left: -35.2%;
z-index: 10;
}
.imagePathBox .share-btns{
display: flex;
justify-content: space-between;
position: fixed;
bottom:150rpx;
width: 72.4%;
left:13.8%;
z-index: 9999;
}
.imagePathBox .share-btn{
font-size: 32rpx;
background-color: #FABE00;
color: #333;
border-radius: 40rpx;
width: 43%;
height: 80rpx;
bottom:30rpx;
padding:0;
margin: 0;
}
.imagePathBox .share-btn::after{
border:none;
}
.close-btn{
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
position: fixed;
height: 20px;
}
.closeBtn{
width: 44rpx;
height: 44rpx;
text-align: center;
vertical-align: middle;
position: fixed;
top:84rpx;
right:84rpx;
}
.previewimg image{
width:100%;
height:100%;
}
3、js
creatShareImageTap(){
var rpx=this.data.rpx;//适配比例
this.setData({
shareMask:false
})
const url=this.data.myUrl
//const url='https://ylhdev.oss-cn-beijing.aliyuncs.com/20200426171219.png'
//开始制作
this.drawCanvas(this.data.details,url,rpx)
},
drawCanvas: function (sourceData,url,rpx){
wx.showLoading({
title: '分享图生成中...'
})
var that=this;
let promise1 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: url,
success: function (res) {
resolve(res);
}
})
});
let promise2 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: sourceData.goodsPicList[0].goodsPicUrl,
success: function (res) {
resolve(res);
}
})
});
let promise3 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: that.data.userInfo.avatarUrl,
success: function (res) {
resolve(res);
}
})
});
Promise.all([
promise1, promise2,promise3
]).then(res=>{
const ctx = wx.createCanvasContext('goods-share');
ctx.setFillStyle("#fff")
ctx.fillRect(0, 0, 375*rpx, 583*rpx)
// ctx.strokeStyle = "white";
// ctx.strokeRect(0,0,375*rpx, 583*rpx);
ctx.setFillStyle('#fff');
ctx.fillRect(0, 375*rpx, 425*rpx, 255*rpx);
ctx.drawImage(res[0].path, 272*rpx, 485*rpx, 82*rpx, 82*rpx)
ctx.drawImage(res[1].path, 0, 0, 375*rpx, 425*rpx)
ctx.save() // 对当前区域保存
ctx.beginPath() // 开始新的区域
ctx.arc(28.5*rpx, 560*rpx, 18*rpx, 0, 2 * Math.PI);
ctx.clip(); // 从画布上裁剪出这个圆形
ctx.drawImage(res[2].path,11.5*rpx, 542*rpx, 35*rpx, 35*rpx)// 把图片填充进裁剪的圆形
ctx.restore() // 恢复
//绘制说明
ctx.setTextAlign('left')
ctx.setFillStyle('#333')
ctx.font='normal bold 16px sans-serif'
// ctx.setFontSize(16)
that.dealWords({
ctx: ctx,//画布上下文
fontSize: 16,//字体大小
word: ' '+sourceData.goodsName,//需要处理的文字
maxWidth: 335*rpx,//一行文字最大宽度
x: 13*rpx,//文字在x轴要显示的位置
y: 425*rpx,//文字在y轴要显示的位置
maxLine: 2//文字最多显示的行数
})
if(sourceData.goodsType==2){
ctx.setFillStyle('#FF5850')
ctx.fillRect(11*rpx, 434*rpx, 33*rpx, 18*rpx)
ctx.setTextAlign('left')
ctx.setFillStyle('#fff')
// ctx.setFontSize(14)
ctx.font='normal normal 14px sans-serif'
ctx.fillText('严选', 13*rpx, 447*rpx)
}
ctx.setTextAlign('left')
ctx.setFillStyle('#F52340')
// ctx.setFontSize(14)
ctx.font='normal normal 14px sans-serif'
ctx.fillText('特权价¥', 11*rpx, 501*rpx)
ctx.setTextAlign('left')
ctx.setFillStyle('#F52340')
ctx.setFontSize(22)
ctx.fillText(sourceData.specialPrice||'0.00',70*rpx, 503*rpx)
ctx.setLineWidth(1);
ctx.setStrokeStyle('#999')
if(JSON.stringify(sourceData.selectPrice).length>2&&sourceData.selectPrice>10){
ctx.moveTo(58*rpx, 521*rpx);
ctx.lineTo(86*rpx, 521*rpx);
}else{
ctx.moveTo(58*rpx, 521*rpx);
ctx.lineTo(80*rpx, 521*rpx);
}
ctx.setTextAlign('left')
ctx.setFillStyle('#999')
// ctx.setFontSize(14)
ctx.font='normal normal 14px sans-serif'
ctx.fillText('售价¥ ' + sourceData.selectPrice,11*rpx,527*rpx)
ctx.setTextAlign('left')
ctx.setFillStyle('#666')
// ctx.setFontSize(14)
ctx.font='normal normal 14px sans-serif'
ctx.fillText(that.data.userInfo.nickName, 51*rpx, 557*rpx)
ctx.setTextAlign('left')
ctx.setFillStyle('#999')
// ctx.setFontSize(10)
ctx.font='normal normal 10px sans-serif'
ctx.fillText('邀请好友享受内部优惠价', 51*rpx, 573*rpx)
ctx.setTextAlign('left')
ctx.setFillStyle('#999')
ctx.setFontSize(10)
ctx.fillText('长按识别', 290*rpx, 584*rpx)
ctx.stroke()
ctx.draw(false,function(){
that.share2();
})
})
},
//文字处理
dealWords: function (options) {
options.ctx.setFontSize(options.fontSize);//设置字体大小
var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);//实际总共能分多少行
var count = allRow >= options.maxLine ? options.maxLine : allRow;//实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数
var endPos = 0;//当前字符串的截断点
for (var j = 0; j < count; j++) {
var nowStr = options.word.slice(endPos);//当前剩余的字符串
var rowWid = 0;//每一行当前宽度
if (options.ctx.measureText(nowStr).width > options.maxWidth) {//如果当前的字符串宽度大于最大宽度,然后开始截取
for (var m = 0; m < nowStr.length; m++) {
rowWid += options.ctx.measureText(nowStr[m]).width;//当前字符串总宽度
if (rowWid > options.maxWidth) {
if (j === options.maxLine - 1) { //如果是最后一行
options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 24); //(j+1)*18这是每一行的高度
} else {
options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 24);
}
endPos += m;//下次截断点
break;
}
}
} else {//如果当前的字符串宽度小于最大宽度就直接输出
options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 24);
}
}
},
//输出图像到canvas容器
share2: function () {
var that = this
wx.canvasToTempFilePath({
canvasId: 'goods-share',
success: function (res) {
console.log('share分享图--------',res)
that.setData({
imagePath: res.tempFilePath,
shareMask:true
})
wx.hideLoading();
},
fail: function (res) {
console.log(res)
}
})
},
//预览
previewImage1: function () {
var that = this
var wximg = that.data.imagePath;
wx.previewImage({
urls: Array(wximg)
})
},
体验线上效果,关注下面云乐汇好物小程序,爆款京东商品,自购省分享赚
关注我个人微信公众号获取更多前端资讯