项目中遇到需要分享到朋友圈,但是查询api发现小程序并没有提供分享到朋友圈的功能,只能实现通过canvas画一张海报然后保存到本地,让用户主动去发朋友圈。
效果图生成后海报
首先使用微信小程序提供的canvasapi将第二张图显示的海报画出来
然后调用保存本地的接口
wx.saveImageToPhotosAlbum({})将图片保存在本地相册中
wxml部分
<view hidden='{{maskFlag==false}}'>
<view class='mask'></view>
<view class='shareWay'>
<view class='selectWay'>
<button class='weixin' open-type="share">
<view class='wechatImg'>
<image class='wechatIcon' src='../../images/wechat.png'></image>
</view>
<view class='sentFriend'>发送给好友</view>
</button>
<view class='middleLine'></view>
<view class='haibao' bindtap='formSubmit'>
<view class='posterImg'>
<image class='posterIcon' src='../../images/haibao.png'></image>
</view>
<view class='createPoster'>生成海报</view>
</view>
<!--生成海报 -->
<view class='imagePathBox' hidden="{{maskHidden == false}}">
<view class='poster'>
<image src="{{imagePath}}" class='shengcheng'></image>
</view>
<button class='baocun' bindtap='savePoster'>保存图片</button>
</view>
<view class="canvas-box">
<canvas style="width: 375px;height: 667px;position:fixed;top:9999px" canvas-id="mycanvas" />
</view>
</view>
<view class='shareEmpty'></view>
<view class='cancel' bindtap='cancelShare'>取消</view>
</view>
</view>
wxss部分
.mask {
width: 100%;
height: 100%;
position: absolute;
background-color: rgb(0, 0, 0);
z-index: 1000;
top: 0;
left: 0;
opacity: 0.5;
}
.shareWay {
width: 750rpx;
height: 372rpx;
border-radius: 10rpx 10rpx 0 0;
/* margin-bottom: 114rpx; */
position: fixed;
bottom: 0;
z-index: 9999;
background-color: #fff;
}
.selectWay {
display: flex;
width: 100%;
height: 250rpx;
justify-content: space-between;
}
.middleLine {
/* width: 1rpx; */
height: 80rpx;
background: rgba(216, 216, 216, 1);
opacity: 0.3;
border: 1rpx solid rgba(151, 151, 151, 1);
margin: 68rpx auto 0;
}
.weixin {
width: 48%;
background-color: #fff;
}
.wechatImg, .posterImg {
width: 88rpx;
height: 88rpx;
margin: 53rpx auto 0;
}
.wechatIcon, .posterIcon {
width: 100%;
height: 100%;
display: block;
}
.sentFriend, .createPoster {
width: 100%;
height: 40rpx;
font-size: 28rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(51, 51, 51, 1);
line-height: 40rpx;
text-align: center;
margin-top: 24rpx;
}
.haibao {
width: 48%;
}
.shareEmpty {
width: 750rpx;
height: 14rpx;
background: rgba(245, 247, 250, 1);
}
.cancel {
width: 100%;
height: 108rpx;
font-size: 32rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(51, 51, 51, 1);
line-height: 108rpx;
text-align: center;
}
.imagePathBox {
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 1);
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
border-top: 2rpx solid rgba(183, 183, 183, 0.2);
z-index: 10;
}
.poster {
width: 670rpx;
height: 959rpx;
background: rgba(255, 255, 255, 1);
position: fixed;
left: 40rpx;
top: 43rpx;
right: 0;
bottom: 0;
border-top: 2rpx solid rgba(183, 183, 183, 0.2);
/* box-shadow: 0px -10px 14px 0px rgba(183,183,183,0.2); */
z-index: 10;
}
.shengcheng {
width: 670rpx;
height: 959rpx;
border-radius: 12rpx;
position: fixed;
left: 40rpx;
top: 43rpx;
box-sizing: border-box;
background-color: #fff;
z-index: 10;
box-shadow: 0px 10px 14px 0px rgba(194, 194, 194, 0.5);
/* padding: 23rpx 21rpx 36rpx; */
}
.baocun {
width: 670rpx;
height: 88rpx;
background: linear-gradient(90deg, rgba(255, 114, 126, 1) 0%, rgba(239, 69, 85, 1) 100%);
box-shadow: 0px 4px 8px 0px rgba(244, 82, 98, 0.45);
border-radius: 8rpx;
display: block;
padding: 0;
line-height: 80rpx;
text-align: center;
position: fixed;
bottom: 40rpx;
left: 40rpx;
color: #fff;
font-size: 32rpx;
}
button[class="baocun"]::after {
border: 0;
}
.cancelFocus {
width: 308rpx;
height: 114rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
line-height: 114rpx;
color: #999;
}
.qrcode {
width: 278rpx;
height: 278rpx;
display: block;
margin: 0 auto;
}
js部分
// 生成海报并分享给好友
//将canvas转换为图片保存到本地,然后将图片路径传给image图片的src
createNewImg: function() {
var that = this;
// console.log(that.data.qrcode)
var context = wx.createCanvasContext('mycanvas');
context.setFillStyle("#ffffff")
context.fillRect(0, 0, 670, 959)
var path = that.data.MainImages;
//将模板图片绘制到canvas,在开发工具中drawImage()函数有问题,不显示图片
context.drawImage(path, 16, 14, 344, 425);
var path1 = that.data.brandImg;
//将模板图片绘制到canvas,在开发工具中drawImage()函数有问题,不显示图片
var path2 = "/images/middle.png";
var path3 = that.data.brandImg;
// var path3 = '../../images/poster.png';
var path4 = that.data.qrcode;
var path5 = "/images/zhiwen.png";
//不知道是什么原因,手机环境能正常显示
context.save(); // 保存当前context的状态
//绘制品牌头像
context.drawImage(path3, 20, 507, 70, 80);
//绘制商品对应的品牌名称
context.setFontSize(18);
context.setFillStyle('#000000');
context.setTextAlign('left');
context.fillText(that.data.Name, 92, 525);
context.stroke();
//绘制扫码即可查看商品更多信息
context.drawImage(path4, 245, 500, 115, 125); //二维码
context.setFontSize(14);
context.setFillStyle('#A0A0A0');
context.setTextAlign('left');
context.fillText(that.data.scan, 65, 618);
context.stroke();
//绘制商品
context.drawImage(path5, 25, 600, 26, 24);
context.stroke();
context.setFontSize(18);
context.setFillStyle('#000000');
context.setTextAlign('left');
context.fillText(that.data.goodsObj.Name, 92, 570);
context.stroke();
//绘制中间分割线
context.drawImage(path2, -8, 455, 390, 45);
context.draw(true, setTimeout(function() {
//将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 670,
height: 959,
destWidth: 2010,
destHeight: 2877,
canvasId: 'mycanvas',
success: function(res) {
var tempFilePath = res.tempFilePath;
that.setData({
imagePath: tempFilePath,
canvasHidden: true
});
},
fail: function(res) {
console.log(res);
}
});
}, 200));
},
//点击保存到相册
savePoster: function() {
var that = this
console.log(that.data.imagePath)
wx.saveImageToPhotosAlbum({
filePath: that.data.imagePath,
success(res) {
wx.showModal({
content: '海报已保存到相册',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: function(res) {
if (res.confirm) {
console.log('999999')
console.log('用户点击确定');
/* 该隐藏的隐藏 */
that.setData({
maskHidden: false
})
}
},
fail: function(res) {
console.log(11111)
}
})
},
fail(res) {
// wx.showToast({
// title: '保存失败',
// icon: 'none',
// })
if (res.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
wx.showModal({
title: '提示',
content: '需要您授权保存相册',
showCancel: false,
success: modalSuccess => {
wx.openSetting({
success(settingdata) {
console.log("settingdata", settingdata)
if (settingdata.authSetting['scope.writePhotosAlbum']) {
wx.showModal({
title: '提示',
content: '获取权限成功,再次点击图片即可保存',
showCancel: false,
})
} else {
wx.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦~',
showCancel: false,
})
}
},
fail(failData) {
console.log("failData", failData)
},
complete(finishData) {
console.log("finishData", finishData)
}
})
}
})
}
}
})
},
//点击生成
formSubmit: function(e) {
var that = this;
this.setData({
maskHidden: false
});
wx.showToast({
title: '海报生成中...',
icon: 'loading',
duration: 1000
});
setTimeout(function() {
wx.hideToast()
that.createNewImg();
that.setData({
maskHidden: true
});
}, 1000)
},
//适配不同屏幕大小的canvas
getQRCodeSize: function() {
var size = 0;
try {
var res = wx.getSystemInfoSync();
var scale = 750 / 278; //不同屏幕下QRcode的适配比例;设计稿是750宽
var width = res.windowWidth / scale;
size = width;
} catch (e) {
// Do something when catch error
// console.log("获取设备信息失败"+e);
}
return size;
},
createQRCode: function(text, size) {
//调用插件中的draw方法,绘制二维码图片
let that = this
// console.log('QRcode: ', text, size)
let _img = QR.createQrCodeImg(text, {
size: parseInt(size)
})
// let qucode = that.data.qucode;
// qucode=_img
that.setData({
'qrcode': _img
})
console.log('商品二维码----->', that.data.qrcode,that.data.qrcode.length)
// 处理二维码成本地图片
base64src(that.data.qrcode, res => {
console.log(res) // 返回图片地址,直接赋值到image标签即可
that.setData({
'qrcode': res
})
});
},
(二维码的处理见下一篇)