效果
封装组件,父组件 ref 调用 downImgUrl()函数,其他根据自己需求改
< 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>
< /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: {
// 下载
downCli ( ) {
if( this.imgUrl && this.imgUrl != '' ) { {
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" >
.flexaround{
display: flex; justify-content: space-around;
}
.flexalign{
display: flex; align-items: center;
}
.font26{
font-size: 26rpx;
font-family: PingFang-SC-Medium;
}
.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>