想要绘制这样的海报
1.结构
//对于微信公众号,可以使用html2canvas将html转成图片然后设置一个图片蒙层,src是转成的图片地址。然后长按保存
鱿鱼圈
SquidTrade
import html2canvas from '@/common/html2canvas.min.js'
2.数据
// 用来控制canvas遮罩层的显示与隐藏
posterInfo: {
status: false,
type:0,
usercode:''
},
img:'' //保存到本地的海报地址
canvasW:0,
canvasH:0,
3.绘制
generatePoster(){
// #ifdef H5
if(this.isweixin){
let that = this
this.$refs.poster.open()
uni.showLoading({
title:'海报生成中。。。'
})
setTimeout(() => {
const dom = document.querySelector('.my-canvas') // 需要生成图片内容的 dom 节点
html2canvas(dom, {
width: dom.clientWidth, //dom 原始宽度
height: dom.clientHeight,
scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
scrollX: 0,
useCORS: true, //支持跨域
scale: 2, // 设置生成图片的像素比例,默认是1,如果生成的图片模糊的话可以开启该配置项
}).then((canvas) => {
// 生成成功
// html2canvas 生成成功的图片链接需要转成 base64位的url
// ownerFun.callMethod('receiveRenderData', canvas.toDataURL('image/png'))
that.img = canvas.toDataURL('image/png')
uni.hideLoading()
console.log(that.img,'图片生成成功')
console.log(canvas,'canvas')
}).catch(err=>{
// 生成失败 弹出提示弹窗
// ownerFun.callMethod('_errAlert',`【生成图片失败,请重试】${err}`)
uni.hideLoading()
console.log(err,'图片生成失败')
})
}, 300)
}else{
this.getPoster()
}
// #endif
// #ifndef H5
this.getPoster()
// #endif
},
// 生成海报
async getPoster(){
uni.showLoading({
title: '海报生成中'
});
let that = this
// 获取设备信息,主要获取宽度,赋值给canvasW 也就是宽度:100%
this.SystemInfo = await this.getSystemInfo();
this.canvasW = this.SystemInfo.windowWidth*0.8; // 画布宽度
this.canvasH = this.SystemInfo.windowHeight*0.7;
this.posterInfo.status = true
let logo = await this.downloadFile(this.logo)
let imgUrl = !!this.goodsDetail.images[0]?this.goodsDetail.images[0]:this.imgUrl
this.goodsImg = await this.downloadFile(imgUrl);
this.ewmImg = await this.downloadFile(this.posterInfo.usercode);
let typeUrl = this.type==1?"":''
var context = uni.createCanvasContext('mycanvas',this)
context.setFillStyle('#fff')
context.fillRect(0,0,this.canvasW,this.canvasH)
context.font = 'normal 400 12px PingFang SC-Bold, PingFang SC'
context.setFillStyle('#999999');
context.fillText('SquidTrade',80,60)
context.setFontSize(12)
context.setFillStyle('#999');
context.fillText('当前价',20,that.canvasH-30)
let priceWidth = context.measureText(this.goodsDetail.now_price).width + 80; //计算昵称宽度,绘制间隔距离
context.setFontSize(12)
context.setFillStyle('#333');
context.fillText('鱿鱼圈',priceWidth,that.canvasH-30)
// 绘制鱿鱼圈
context.setFillStyle('#333')
context.font = 'normal bold 16px PingFang SC-Bold, PingFang SC'
context.fillText('鱿鱼圈', 80, 40);
// 绘制商品名称
// context.setFontSize(16);
context.setFillStyle('#333');
context.font = 'normal bold 16px PingFang SC-Bold, PingFang SC'
context.fillText(this.goodsDetail.title,20,that.canvasH-54)
// 绘制商品价格
context.setFontSize(20)
context.setFillStyle('#D50000');
context.fillText(this.goodsDetail.now_price,60,that.canvasH-30)
//绘制头像
context.save()
context.beginPath();
context.arc(44, 44, 22, 0, 2 * Math.PI)
context.clip();
context.drawImage(logo.tempFilePath, 22, 22, 44, 44);
context.restore();
context.draw(true);
// 商品图片
context.drawImage(this.goodsImg.tempFilePath, 20, 80, that.canvasW-40, that.canvasH-170);
context.draw(true);
// 二维码
context.drawImage(this.ewmImg.tempFilePath, that.canvasW-80, that.canvasH-80, 70, 70);
context.draw(true);
uni.hideLoading()
},
// 获取设备信息
getSystemInfo(){
return new Promise((req, rej) => {
uni.getSystemInfo({
success: function (res) {
req(res)
}
});
})
},
downloadFile(image) {
return new Promise((req, rej) => {
uni.downloadFile({
url: image,
success: function(res) {
req(res)
},
});
})
},
4.点击保存按钮保存海报
save(){
let that = this
uni.canvasToTempFilePath({
fileType: 'jpg',
canvasId: 'mycanvas',
quality: 1,
success: (res) => {
that.img = res.tempFilePath
console.log(res.tempFilePath,'海报地址')
that.download()
},
fail: function(err) {
console.log(err)
// reject(err)
}
},this)
},
download(){
let that = this
console.log(this.img,'图片img')
// 先下载图片
uni.downloadFile({
url:this.img,
success: (res) => {
console.log(res.tempFilePath,'下载后的图片地址')
// #ifdef H5
const imgUrl = res.tempFilePath;
if(that.isweixin){
uni.showToast({
icon:'none',
title:'请长按图片保存'
})
// that.preview(res.tempFilePath)
// let canvas = document.querySelector('.my-canvas');
// Canvas2Image.saveAsImage(canvas, this.canvasW, this.canvasH, 'png','商品分享');
}else{
var oA = document.createElement("a");
oA.download = '下载图片'; // 设置下载的文件名,默认是'下载'
oA.href = imgUrl;
console.log(oA ,'按钮a')
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
}
// #endif
// #ifdef MP-WEIXIN
// 获取到图片本地地址后再保存图片到相册(因为此方法不支持远程地址)
// that.preview()
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: "保存成功!",
});
},
fail: () => {
uni.showToast({
title: "保存失败",
});
},
});
// #endif
},
});
},
css:
.my-canvas-box {
width: 750rpx;
height: 100%;
position: fixed;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 99;
&.hide {
display: none;
}
&.show {
display: block;
}
.canvas-tip {
color: #ffffff;
font-size: 24rpx;
margin-top: 30rpx;
text-align: center;
}
.my-canvas {
width: 614rpx;
height: 907rpx;
background: #FFFFFF;
border-radius: 24rpx;
margin: 155rpx auto 0;
}
.btn{
margin: 30rpx auto 0;
width: 614rpx;
height: 87rpx;
line-height: 87rpx;
background: #FFD14A;
border-radius: 44rpx;
}
}
.poster-pop{
position: relative;
.my-canvas{
width: 614rpx;
height: 907rpx;
background: #FFFFFF;
border-radius: 24rpx;
.canvas-top{
padding: 20rpx;
image{
width: 88rpx;
height: 88rpx;
border-radius: 50%;
margin-right: 7rpx;
}
}
.poster-centent{
padding: 0 30rpx 30rpx;
}
.goodsimg{
width: 555rpx;
height: 555rpx;
position: relative;
image{
width: 100%;
height: 100%;
}
.goods-type{
width: 97rpx;
height: 97rpx;
position: absolute;
top:0;
left:0
}
}
.goodsmessage{
margin-top: 38rpx;
image{
width: 140rpx;
height: 140rpx;
}
.startprice{
margin: 0 8rpx 0 14rpx;
}
}
}
.img-box{
width: 614rpx;
height: 907rpx;
border-radius: 24rpx;
position: absolute;
top: 0;
left: 0;
}
.btn{
margin: 30rpx auto 0;
width: 614rpx;
height: 87rpx;
line-height: 87rpx;
background: #FFD14A;
border-radius: 44rpx;
text-align: center;
}
}