1.html部分
.canvas-box{
width: 100%;
position: fixed;
left: 0;
top: 999999rpx;
}
<button class="savesharebtn" open-type="openSetting" bindopensetting="handleSetting" wx:if="{{(!isGroupon) && (!canWrite)}}" >
<image class='sharebtn_image' src='/static/images/friend.png'></image>
<view class='sharebtn_text'>发朋友圈</view>
</button>
<button class="savesharebtn" bindtap="saveShare" wx:if="{{!isGroupon && canWrite}}">
<image class='sharebtn_image' src='/static/images/friend.png'></image>
<view class='sharebtn_text'>发朋友圈</view>
</button>
<view class="canvas-box">
<canvas id="myCanvas" canvas-id="myCanvas" style="width:{{windowWidth}}px;height:{{windowHeight}}px;"></canvas>
</view>
其中windowWidth、windowHeight是通过wx.getSystemInfoSync()获取的,否则绘制canvas会变形代码如下:
that.setData({
windowWidth: wx.getSystemInfoSync().windowWidth,
windowHeight: wx.getSystemInfoSync().windowHeight,
});
2.js部分
其中图片的宽和高要按照图片的比例来进行绘制,我使用的图片是1:1的,所以图片的宽高都是媒体的宽度。
canvas画布转成图片时,destWidth、destHeight决定了保存下来的图片像素问题,一般为绘制图片的2或者3倍,否则图片会模糊:
destWidth: that.data.windowWidth*3,
destHeight: (that.data.windowWidth+100)*3,
// 保存分享图
saveShare: function() {
let that = this;
console.log(that);
//canvas画布在上面绘制图片,如果图片是请求的后台线上时,需要使用wx.downloadFile下载下来,本地的则不需要
wx.downloadFile({
url: that.data.shareImage,
success: function(res) {
that.setData({
shareImage: res.tempFilePath
})
that.drawImage();
setTimeout(function () {
that.canvasToImage()
}, 200)
},
fail: function() {
console.log('fail')
}
})
},
drawImage() {
wx.showLoading({
title: '图片生成中...',
});
//绘制canvas图片
var that = this
var ctx = wx.createCanvasContext('myCanvas'); //绘图上下文
// console.log(wx.getSystemInfoSync());
var w = wx.getSystemInfoSync().windowWidth;
var h = wx.getSystemInfoSync().windowHeight;
// ctx.clearRect(0, 0, w, h)
console.log(that.data.windowWidth);
that.setData({
windowWidth: w,
windowHeight: h,
scale: 1.6
})
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, w, h);
//ctx.drawImage('../../static/images/img-share.png', 0, 0, w, w);
ctx.drawImage(that.data.shareImage, 0, 0, w, w);
ctx.setFillStyle('#333333');
ctx.setFontSize(16);
// var content = '马克华菲女装2020春新品雪纺衬衫女荷叶边宽松洋气小衫仙气上衣,马克华菲女装2020春新品雪纺衬衫女荷叶边宽松洋气小衫仙气上衣';
var content = that.data.goods.brief;
console.log(that.data.goods.brief);
// var content = '宠友们快来围观萌宠靓照'
var textareaWidth = Math.ceil(w / 16);
// that.setData({
// checkedSpecPrice: '99.00'
// })
//根据ctx.measureText(that.data.checkedSpecPrice.toString()).width获取文本所占宽度
var priceArea = Math.ceil(ctx.measureText(that.data.checkedSpecPrice.toString()).width + 55);
console.log(priceArea);
if (content.length <= textareaWidth-4) {
// 不用换行
ctx.fillText(content, 10, w, w);
// 绘制价格
ctx.setFillStyle('red')
ctx.setFontSize(20);
ctx.fillText('¥' + that.data.checkedSpecPrice, 10, w + 35, priceArea);
ctx.setFillStyle('#888888')
ctx.setFontSize(14);
ctx.fillText('原价:¥' + that.data.goods.counterPrice, priceArea, w + 35, 200);
} else if (content.length <= textareaWidth * 2 - 10) {
// 两行
let firstLine = content.substring(0, textareaWidth);
let secondLine = content.substring(textareaWidth, textareaWidth * 2 - 4);
ctx.fillText(firstLine, 10, w, w-20);
ctx.fillText(secondLine, 10, w+22, w-20);
// 绘制价格
ctx.setFillStyle('red')
ctx.setFontSize(20);
ctx.fillText('¥' + that.data.checkedSpecPrice, 10, w + 60, priceArea);
ctx.setFillStyle('#888888')
ctx.setFontSize(14);
ctx.fillText('原价:¥' + that.data.goods.counterPrice, priceArea, w + 60, 200);
} else {
// 超过两行
let firstLine = content.substring(0, textareaWidth);
let secondLine = content.substring(textareaWidth, textareaWidth*2-4) + '...';
ctx.fillText(firstLine, 10, w, w-20);
ctx.fillText(secondLine, 10, w+22, w-20);
// 绘制价格
ctx.setFillStyle('red')
ctx.setFontSize(20);
ctx.fillText('¥' + that.data.checkedSpecPrice, 10, w + 60, priceArea);
ctx.setFillStyle('#888888')
ctx.setFontSize(14);
ctx.fillText('原价:¥' + that.data.goods.counterPrice, priceArea, w + 60, 200);
}
ctx.draw()
},
canvasToImage() {
var that = this
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.windowWidth,
height: that.data.windowWidth+100,
destWidth: that.data.windowWidth*3,
destHeight: (that.data.windowWidth+100)*3,
canvasId: 'myCanvas',
success: function (res) {
wx.hideLoading();
// wx.previewImage长按图片保存图片的功能
// wx.previewImage({
// current: res.tempFilePath, // 当前显示图片的http链接
// urls: [res.tempFilePath] // 需要预览的图片http链接列表
// })
//直接保存手机相册
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function (res) {
wx.showModal({
title: '存图成功',
content: '图片成功保存到相册了,可以分享到朋友圈了',
showCancel: false,
confirmText: '好的',
confirmColor: '#a78845',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
}
}
})
},
fail: function (res) {
console.log('fail')
}
})
},
fail: function (err) {
console.log('失败')
console.log(err)
}
})
},
3.保存手机相册授权功能
onLoad: function(options) {
let that = this;
that.setData({
windowWidth: wx.getSystemInfoSync().windowWidth,
windowHeight: wx.getSystemInfoSync().windowHeight,
});
wx.getSetting({
success: function (res) {
console.log(res)
//不存在相册授权
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success: function () {
that.setData({
canWrite: true
})
},
fail: function (err) {
that.setData({
canWrite: false
})
}
})
} else {
that.setData({
canWrite: true
});
}
}
})
},
handleSetting: function(e) {
var that = this;
// console.log(e)
if (!e.detail.authSetting['scope.writePhotosAlbum']) {
wx.showModal({
title: '警告',
content: '不授权无法保存',
showCancel: false
})
that.setData({
canWrite: false
})
} else {
wx.showToast({
title: '保存成功'
})
that.setData({
canWrite: true
})
}
},
绘制效果图: