效果
封装组件,父组件 ref 调用 downImgUrl()函数,其他根据自己需求改
//(内容,扫码打开的页面)
this.$refs.canvasImg.downImgUrl(this.detail,'/pagesA/detail/postDetail?id='+this.detailID)
<template>
<view>
<view class="bgpart">
<canvas class="canvas-wrap" canvas-id="canvasID" type="2d"></canvas>
<view class="popPart">
<view>
<view class="share-list">
<view class="share-item flexaround flexalign" @click="shareToFriend(1)">
<view class="iconImg flexalign flexaround">
<image src="/static/sharePop/share1.png" mode=""></image>
</view>
<text class="font26" style="margin-top: 16rpx;">微信</text>
</view>
<view class="share-item flexaround flexalign" @click="shareToFriend(2)">
<view class="iconImg flexalign flexaround">
<image src="/static/sharePop/share2.png" mode=""></image>
</view>
<text class="font26" style="margin-top: 16rpx;">朋友圈</text>
</view>
<view class="share-item flexaround flexalign" @click="downCli">
<view class="iconImg flexalign flexaround" style="width: 88rpx;height: 88rpx;">
<u-icon name="download" size="30"></u-icon>
</view>
<text class="font26" style="margin-top: 16rpx;">下载</text>
</view>
</view>
</view>
<view class="share-header flexalign flexaround" style="background: #fff;" @click="$emit('close')">
取消
</view>
</view>
</view>
<permission ref="permission"></permission>
</view>
</template>
<script>
import {
indexsettingPoster
} from "@/api/all.js"
export default {
name: "sharePoster",
props: {},
data() {
return {
logo: '/static/logo.png',
bgimg: '',
detail: {},
imgUrl:'',//完成海报图
qrCode:''
};
},
created() {
},
methods: {
shareToFriend(e){
if(e == 1){ //微信
uni.share({
provider: "weixin",
scene: "WXSceneSession",
type: 2,
imageUrl: this.imgUrl,
success: function (res) {
console.log(res)
},fail: function (err) {
console.log(err)
// this.com.msg('')
}
});
}else{ //朋友圈
uni.share({
provider: "weixin",
scene: "WXSenceTimeline",
type: 2,
imageUrl: this.imgUrl,
success: function (res) {
console.log(res)
},fail: function (err) {
console.log(err)
// this.com.msg('失败')
}
});
}
},
// 下载
downCli() {
if( this.imgUrl && this.imgUrl != ''){
this.$refs.permission.requestPermission('photoLibrary').then(async res => {
uni.saveImageToPhotosAlbum({
filePath: this.imgUrl,
success: function () {
console.log('save success');
uni.showToast({
icon:"none",
title:'已下载'
})
}
});
})
}
},
async downImgUrl(e,url,type) {
await indexsettingPoster({url:url}).then(res => {
this.bgimg = res.data.posterThumb
this.qrCode = res.data.qrCode
})
let canW = 320;
let canH = 450;
let ctx = uni.createCanvasContext('canvasID', this);
// ctx.setFillStyle("transparent"); //设置canvas背景颜色
// ctx.fillRect(0, 0, 346, 500) //设置canvas画布大小
ctx.drawImage(this.bgimg, 0, 0, canW, canH) //背景
ctx.drawImage(this.logo, 18, 20, 36, 36) //logo
// ctx.drawImage(e.dynamicQRcode, 255, 370, 70, 70) //二维码
ctx.drawImage(this.qrCode, 230, 370, 70, 70) //二维码
//绘制圆形头像
this.drawCircular(ctx, e.headPortrait, 26, 398, 40, 40)
// 名字
ctx.setFontSize(14)
ctx.setFillStyle("#ffffff")
ctx.fillText(e.nickName, 74, 424)
// 绘制标题,多余文字自动换行
ctx.setFontSize(26)
ctx.setFillStyle("#2C3E68")
ctx.textAlign = "center"
let str = type ? e.teamName : e.dynamicTitle
// 字符串总长度
let _strLength = str.length > 24 ? 24 : str.length
// 总结截取次数
let _strNum = Math.ceil(_strLength / 8)
// 每次开始截取字符串的索引
let _strHeight = 0
// 绘制的字体 x,y的初始位置
let _strX = 345 / 2,
_strY = 90
let strIndex = 223
// 开始截取
for (let i = 0; i < _strNum; i++) {
strIndex = _strY + i * 40
ctx.fillText(str.substr(_strHeight + i * 9, 9), _strX, _strY + i * 34)
}
// 绘制内容
ctx.setFontSize(13)
ctx.setFillStyle("#4FB0FF")
let cont = type ? e.teamContent : e.dynamicDescribe
// 字符串总长度
let _contLength = cont.length > 120 ? 120 : cont.length
// 总结截取次数
let _contNum = Math.ceil(_contLength / 20)
// 每次开始截取字符串的索引
let _contHeight = 0
// 绘制的字体 x,y的初始位置
let _contX = 345 / 2,
_contY = 180
let contIndex = 223
// 开始截取
for (let i = 0; i < _contNum; i++) {
contIndex = _contY + i * 20
ctx.fillText(cont.substr(_contHeight + i * 20, 20), _contX, _contY + i * 22)
}
//详情图
let img = type ? e.teamPics : e.dynamicPics //团队,动态
img.split(',').forEach((el,index)=>{
if(index == 0){
ctx.drawImage( el , 50, 290, 70, 70) //二维码
}else if(index == 1){
ctx.drawImage( el , 130, 290, 70, 70) //二维码
}else if(index == 2){
ctx.drawImage( el , 210, 290, 70, 70) //二维码
}
})
ctx.draw(false, () => {
// 返回canvas图片信息
uni.canvasToTempFilePath({
canvasId: 'canvasID',
success: (res) => {
this.imgUrl = res.tempFilePath
},
fail: function(err) {
console.log(err)
}
})
})
},
// 绘制圆形头像
drawCircular(ctx, url, x, y, width, height) {
//画圆形头像
var avatarurl_width = width;
var avatarurl_heigth = height;
var avatarurl_x = x;
var avatarurl_y = y;
ctx.save(); //先保存状态,已便于画完园再用
ctx.beginPath(); //开始绘制
ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math
.PI * 2, false);
ctx.setFillStyle("#FFFFFF")
ctx.fill() //保证图片无bug填充
ctx.clip(); //剪切
ctx.drawImage(url, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); //推进去图片
ctx.restore();
},
}
}
</script>
<style scoped lang="scss">
.canvas-wrap {
margin: 20% 45rpx;
width: calc(100% - 90rpx);
height: 940rpx;
// background-color:
}
.bgpart {
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
left: 0;
top: 0;
z-index: 99;
.popPart {
width: 100%;
height: 360rpx;
background-color:
border-radius: 20rpx 20rpx 0 0;
position: fixed;
left: 0;
bottom: 0;
z-index: 99;
}
}
.share-header {
line-height: 80rpx;
}
.share-list {
margin: 20rpx 0 60rpx 0;
display: flex;
/* flex-direction: row; */
flex-wrap: wrap;
.share-item {
margin-top: 30rpx;
min-width: 20%;
flex-direction: column;
.iconImg {
background-color:
border-radius: 50%;
image {
width: 88rpx;
height: 88rpx;
}
}
}
}
</style>