uniapp项目中使用canvas生成海报并保存、微信分享、发送至朋友圈
1.html
<!-- 分享模态框 -->
<canvas canvas-id="poster" class="poster-canvas"></canvas>
<view class="share-mask" v-if="isShowShare" @click="isShowShare = false">
<view class="share-container" @click.stop>
<u-image width="600rpx" height="600rpx" :src="goodsInfo.image" ></u-image>
<view class="share-til line1">{{goodsInfo.goods_name}}</view>
<view class="share-price">¥{{goodsInfo.price}}</view>
<image class="share-code" :src="shareCode" ></image>
</view>
<view class="share-bot" @click.stop>
<view class="share-btns">
<view class="btns-list" @click="onAppShare">
<image src="/static/image/wx_icon.png" class="btn" mode=""></image>
<text>微信</text>
</view>
<view class="btns-list" @click="onFriendShare">
<image src="/static/image/friend_icon.png" class="btn" mode=""></image>
<text>朋友圈</text>
</view>
<view class="btns-list" @click="onSaveImg">
<image src="/static/image/save_icon.png" class="btn" mode=""></image>
<text>保存本地</text>
</view>
</view>
<view class="share-cancel" @click="isShowShare = false">取消</view>
</view>
</view>
2.js
// 创建海报
createPoster() {
const that = this;
return new Promise((resolve, reject) => {
uni.showLoading({
title: '海报生成中'
});
const ctx = uni.createCanvasContext('poster');
ctx.fillRect(0, 0, 300, 460);
ctx.setFillStyle("#FFF");
ctx.fillRect(0, 0, 300, 460);
//商品图片下载
uni.downloadFile({
// url: "https://tianseapi.jujiangsoft.com/storage/images/2021_08_02/95e8dcdeac7156a38f205d5b0b71d521918.jpg",
url: that.goodsInfo.image,
success: (res) => {
console.log('商品图片下载',res)
if (res.statusCode === 200) {
ctx.drawImage(res.tempFilePath, 0, 0, 300, 300);
// 二维码图片下载
uni.downloadFile({
// url: "https://tianseapi.jujiangsoft.com/storage/images/2021_08_02/95e8dcdeac7156a38f205d5b0b71d521918.jpg",
url: that.shareCode,
success: (res2) => {
console.log("二维码图片下载",res2);
if (res2.statusCode === 200) {
// 商品标题
ctx.setFontSize(14);
ctx.setFillStyle('#222222');
ctx.fillText(that.goodsInfo.goods_name, 15, 325);
// 商品价格
ctx.setFontSize(18);
ctx.setFillStyle('#222222');
ctx.fillText('¥'+that.goodsInfo.price, 15, 368);
// // 长按识别二维码访问
// ctx.setFontSize(19);
// ctx.setFillStyle('#333');
// ctx.fillText("长按识别二维码访问", 17, textTop + 136);
// // 平台名称
// ctx.setFontSize(16);
// ctx.setFillStyle('#999');
// ctx.fillText(that.platformName, 17, textTop + 170);
// 二维码
ctx.drawImage(res2.tempFilePath, 196, 354, 89, 89);
ctx.draw(true, () => {
// canvas画布转成图片并返回图片地址
uni.canvasToTempFilePath({
canvasId: 'poster',
width: 300,
height: 460,
success: (res) => {
console.log("生成海报",res);
resolve(res.tempFilePath);
},
fail: () => {
uni.hideLoading();
reject();
}
})
});
} else {
uni.hideLoading();
console.log('海报第四步')
uni.showToast({
title: '海报制作失败,图片下载失败',
icon: 'none'
});
}
},
fail: err => {
console.log('海报第三步',err)
uni.hideLoading();
uni.showToast({
title: '海报制作失败,图片下载失败',
icon: 'none'
});
}
});
} else {
console.log('海报第er步')
uni.hideLoading();
uni.showToast({
title: '海报制作失败,图片下载失败',
icon: 'none'
});
}
},
fail: err => {
console.log('海报第一步',err)
uni.hideLoading();
uni.showToast({
title: '海报制作失败,图片下载失败',
icon: 'none'
});
}
});
});
},
// 保存图片
async onSaveImg() {
const that = this;
let imgUrl = await that.createPoster();
console.log("保存图片-海报生成图片",imgUrl);
// // #ifdef H5
// that.h5SaveImg = imgUrl;
// uni.hideLoading();
// // #endif
// #ifdef MP-WEIXIN
uni.showLoading({
title: '海报下载中'
});
if (settingWritePhotosAlbum) {
uni.getSetting({
success: res => {
if (res.authSetting['scope.writePhotosAlbum']) {
uni.saveImageToPhotosAlbum({
filePath: imgUrl,
success: () => {
uni.hideLoading();
uni.showToast({
title: '保存成功'
});
}
});
} else {
uni.showModal({
title: '提示',
content: '请先在设置页面打开“保存相册”使用权限',
confirmText: '去设置',
cancelText: '算了',
success: data => {
if (data.confirm) {
uni.hideLoading();
uni.openSetting();
}
}
});
}
}
});
} else {
settingWritePhotosAlbum = true;
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
uni.saveImageToPhotosAlbum({
filePath: imgUrl,
success: () => {
uni.hideLoading();
uni.showToast({
title: '保存成功'
});
}
});
}
});
}
// #endif
// #ifdef APP-PLUS
uni.showLoading({
title: '海报下载中'
});
uni.saveImageToPhotosAlbum({
filePath: imgUrl,
success: () => {
uni.hideLoading();
uni.showToast({
title: '保存成功'
});
}
});
// #endif
},
// 微信分享
async onAppShare() {
const that = this;
let imgUrl = await that.createPoster();
console.log("微信分享-海报生成图片",imgUrl);
uni.hideLoading();
// let arr = [];
// arr[0] = imgUrl;
// plus.share.sendWithSystem({content:'',href:'',pictures:arr}, function(){
// console.log('分享成功');
// }, function(e){
// console.log('分享失败:'+JSON.stringify(e));
// });
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
type: 2,
// title: '你好呀',
// href: 'https://www.baidu.com/',
// summary: '我是图文描述',
imageUrl: imgUrl,
success: function(res) {
console.log('success:' + JSON.stringify(res));
},
fail: function(err) {
console.log('fail:' + JSON.stringify(err));
}
});
},
//微信朋友圈分享
async onFriendShare(){
const that = this;
let imgUrl = await that.createPoster();
console.log("微信分享-海报生成图片",imgUrl);
uni.hideLoading();
uni.share({
provider: 'weixin',
scene: 'WXSenceTimeline',
type: 2,
// title: '你好呀',
// href: that.dataInfo.share.shareUrl,
// summary: that.dataInfo.share.shareContent,
// imageUrl: that.dataInfo.share.shareImg,
imageUrl: imgUrl,
success: function(res) {
console.log('success:' + JSON.stringify(res));
},
fail: function(err) {
console.log('fail:' + JSON.stringify(err));
}
});
},
3.css
//分享模态框
.poster-canvas {
position: fixed;
top: -10000rpx;
left: 0rpx;
width:600rpx;
height:920rpx;
}
.share-mask{
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,.5);
}
.share-container{
position: absolute;
left: 75rpx;
top: 100rpx;
width:600rpx;
height:920rpx;
background: #FFFFFF;
}
.share-til{
width: 100%;
margin-top:40rpx;
padding:0 30rpx;
font-size: 28rpx;
color: #222222;
}
.share-price{
margin-top:50rpx;
padding:0 30rpx;
font-size: 28rpx;
color: #222222;
}
.share-code{
position: absolute;
// right: 30rpx;
// bottom: 30rpx;
left: 392rpx;
top: 708rpx;
width: 178rpx;
height: 178rpx;
background-color: #fff;
}
.share-bot{
position: absolute;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 250rpx;
background: #FFFFFF;
}
.share-btns{
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
height: 160rpx;
padding: 30rpx 0;
border-bottom: 1rpx solid #EEEEEE;
}
.btns-list{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex: 1;
height: 100%;
justify-content: center;
}
.btn{
width: 60rpx;
height: 60rpx;
}
.share-cancel{
width: 100%;
font-size: 24rpx;
color: #222222;
line-height: 90rpx;
text-align: center;
}