sadjv3_jishi/pages/poster/poster.vue

200 lines
7.6 KiB
Vue

<template>
<view class="content" v-if="isShow" @click.stop="isShow=false">
<canvas @click.stop="" :style="{ width: canvasW + 'px', height: canvasH + 'px' }" canvas-id="my-canvas"></canvas>
<view class="save-btn" @click.stop="saveImage">保存海报</view>
</view>
</template>
<script>
export default{
props:{
headerImg:{
type: String,
default: 'https://zhaixiandaojia.com/public/uploads/20210123/f87969714ba1d865f2366b997cbd9fd8.jpg'
},
title:{
type: String,
default: '盛安小象'
},
subTitle:{
type: String,
default: '盛安小象'
},
content:{
type: String,
default: "推荐码"
},
abImg:{
type: String,
default: 'https://zhaixiandaojia.com/public/uploads/20210123/f87969714ba1d865f2366b997cbd9fd8.jpg'
}
},
data(){
return {
canvasW: 0,
canvasH: 0,
ctx: null,
isShow: false,
qrcode: ''
}
},
methods:{
//显示
showCanvas(headerImg, qrcode){
this.isShow = true
this.qrcode = qrcode
this.headerImg = headerImg
this.__init()
},
//初始化画布
async __init(){
uni.showLoading({
title: '加载中...',
mask: true
})
this.ctx = uni.createCanvasContext('my-canvas',this)
this.canvasW = uni.upx2px(550);
this.canvasH = uni.upx2px(900);
//设置画布背景透明
this.ctx.setFillStyle('rgba(255, 255, 255, 0)')
//设置画布大小
this.ctx.fillRect(0,0,this.canvasW,this.canvasH)
//绘制圆角背景
this.drawRoundRect(this.ctx, 0, 0, this.canvasW, this.canvasH,uni.upx2px(18),'#FFFFFF')
//获取标题图片
let headerImg = await this.getImageInfo(this.headerImg)
let hW = uni.upx2px(500);
let hH = uni.upx2px(700);
//绘制标题图
this.drawRoundImg(this.ctx,headerImg.path,((this.canvasW-hW) / 2),((this.canvasW-hW) / 2),hW,hH,uni.upx2px(16))
//绘制标题
this.ctx.setFontSize(14); //设置标题字体大小
this.ctx.setFillStyle('#333'); //设置标题文本颜色
this.ctx.fillText(this.title,((this.canvasW-hW) / 2)+uni.upx2px(120),(((this.canvasW-hW) / 2) + hH + uni.upx2px(80)))
//绘制内容
if(this.content){
//console.log(this.content)
this.ctx.setFontSize(14);
this.ctx.setFillStyle('#999');
/* this.ctx.fillText('¥',((this.canvasW-hW) / 2),(((this.canvasW-hW) / 2) + hH + uni.upx2px(120))) */
this.ctx.setFontSize(12);
this.ctx.fillText("邀请码:"+this.content,(((this.canvasW-hW) / 2) + uni.upx2px(120)),(((this.canvasW-hW) / 2) + hH + uni.upx2px(130)))
}
//绘制头像
let BottomAdImg = await this.getImageInfo(this.abImg)
this.ctx.drawImage(BottomAdImg.path, 16, (((this.canvasW-hW) / 2) + hH + uni.upx2px(40)), 50, 50)
//延迟渲染
setTimeout(()=>{
this.ctx.draw(true,()=>{
uni.hideLoading()
})
},500)
},
//带圆角图片
drawRoundImg(ctx, img, x, y, width, height, radius){
ctx.beginPath()
ctx.save()
// 左上角
ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 1.5)
// 右上角
ctx.arc(x + width - radius, y + radius, radius, Math.PI * 1.5, Math.PI * 2)
// 右下角
ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI * 0.5)
// 左下角
ctx.arc(x + radius, y + height - radius, radius, Math.PI * 0.5, Math.PI)
ctx.stroke()
ctx.clip()
ctx.drawImage(img, x, y, width, height);
ctx.restore()
ctx.closePath()
},
//圆角矩形
drawRoundRect(ctx, x, y, width, height, radius, color){
ctx.save();
ctx.beginPath();
ctx.setFillStyle(color);
ctx.setStrokeStyle(color)
ctx.setLineJoin('round'); //交点设置成圆角
ctx.setLineWidth(radius);
ctx.strokeRect(x + radius/2, y + radius/2, width - radius , height - radius );
ctx.fillRect(x + radius, y + radius, width - radius * 2, height - radius * 2);
ctx.stroke();
ctx.closePath();
},
//获取图片
getImageInfo(imgSrc){
return new Promise((resolve, reject) => {
console.log("图片链接",imgSrc)
console.log("图片类型",typeof imgSrc)
uni.getImageInfo({
src: imgSrc,
success: (image) => {
resolve(image);
console.log('获取图片成功',image)
},
fail: (err) => {
reject(err);
console.log('获取图片失败',err)
uni.hideLoading()
uni.showToast({
title: '获取图片失败'
});
}
});
});
},
//保存图片到相册
saveImage(){
var that = this
uni.showLoading({
title: '正在加载',
mask: false
});
uni.canvasToTempFilePath({
canvasId: 'my-canvas',
quality: 1,
complete: (res) => {
console.log('保存到相册',res);
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
uni.hideLoading();
uni.showToast({
title: '已保存到相册',
icon: 'success',
duration: 2000
})
setTimeout(()=>{
that.isShow = false
},2000)
}
})
}
},this);
}
}
}
</script>
<style scoped lang="scss">
.content{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999999;
background: rgba(0,0,0,.4);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.save-btn{
margin-top: 35rpx;
color: #FFFFFF;
background-image: linear-gradient(-45deg, #17bd6e, #019c88);
padding: 15rpx 40rpx;
border-radius: 50rpx;
}
}
</style>