<template>
|
|
<view class="pages">
|
|
<!-- 海报 -->
|
|
<view class="">
|
|
<canvas :style="{ width: canvasW + 'px', height: canvasH + 'px' }" canvas-id="myCanvas" id="myCanvas"></canvas>
|
|
</view>
|
|
<!-- 按钮生成图片 -->
|
|
<cover-view class="btn flex align-center justify-center" @click="saveImg_btn">
|
|
<button class="btn_save">{{tbn_text}}</button>
|
|
</cover-view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
IMG_URL_SHARE,
|
|
IMG_URL
|
|
} from '@/env.js';
|
|
export default {
|
|
data() {
|
|
return {
|
|
IMG_URL_SHARE, //图片二维码主路径
|
|
IMG_URL, // 正常商品图片路径
|
|
tbn_text: '保存图片',
|
|
canvasW: 0, // 画布宽
|
|
canvasH: 0, // 画布高
|
|
SystemInfo: {}, // 设备信息
|
|
goodsId: '', // 商品id 用于请求二维码
|
|
pageTitleImg: 'goods/share_title.png', //页面内容标题的图片
|
|
pageTitleImgH: 0, //页面内容标题的图片高度
|
|
pagesTitle: "", //页面内容标题
|
|
goodsImg: '', // 商品主图
|
|
goodsImgH: 0, //商品主图高度
|
|
ewmImg: '', // 二维码图片
|
|
ewmImgH: 0, //二维码图片高度
|
|
ewmW: 120, // 二维码大小
|
|
title: '', // 商品标题
|
|
price: '', // 价格
|
|
Oldprice: '', // 原价
|
|
name: '', // 推荐人
|
|
nameURL: '', // 推荐人头像
|
|
nameURLW: 0, // 推荐人头像宽度
|
|
nameURLH: 0, // 推荐人头像高度
|
|
alt: '', //推荐语,
|
|
price_new: '', //本网价
|
|
price_old: "", //市价
|
|
SystemInfo:null, // 设备信息
|
|
}
|
|
},
|
|
async onLoad(option) {
|
|
uni.showToast({
|
|
icon: 'loading',
|
|
mask: true,
|
|
duration: 10000,
|
|
title: '海报绘制中',
|
|
});
|
|
|
|
|
|
this.getSystemInfo().then(res => {
|
|
// console.log(res, "设备信息");
|
|
this.SystemInfo = res;
|
|
});
|
|
this.SystemInfo = uni.getSystemInfoSync()
|
|
|
|
// 商品信息
|
|
const goodsInfo = JSON.parse(decodeURIComponent(option.goodsInfo));
|
|
const shareInfo = JSON.parse(decodeURIComponent(option.shareInfo));
|
|
// console.log(goodsInfo, '商品信息')
|
|
// 用户信息
|
|
this.userInfo = uni.getStorageSync("__user_info");
|
|
// console.log(this.userInfo, "userINfo")
|
|
this.nameURL = this.userInfo.headUrl; // 推荐人头像
|
|
|
|
this.name = this.userInfo.nickName; // 推荐人姓名
|
|
this.goodsImg = goodsInfo.pic[0]; // 商品图片
|
|
this.goodsId = goodsInfo.id; // 商品id
|
|
this.price = goodsInfo.payMoney // 价格
|
|
this.Oldprice = goodsInfo.price // 原价
|
|
this.title = `【${goodsInfo.subTitle}】${goodsInfo.title}` // 商品标题
|
|
// 获取推荐信息
|
|
this.alt = shareInfo.alt;
|
|
this.pagesTitle = shareInfo.title;
|
|
this.ewmImg = shareInfo.img
|
|
//页面标题图片
|
|
const pageTitleImgH = await this.getImageInfo(this.IMG_URL + this.pageTitleImg);
|
|
this.pageTitleImgH = pageTitleImgH.height / 2;
|
|
// 推荐人头像
|
|
const nameURLH = await this.getImageInfo(this.nameURL);
|
|
// console.log(nameURLH, "toxxzczx")
|
|
this.nameURLW = nameURLH.width / 2
|
|
this.nameURLH = nameURLH.height / 2;
|
|
// 商品主图高度
|
|
// console.log(this.goodsImg, '商品主图高度')
|
|
const goodsImgH = await this.getImageInfo(this.goodsImg);
|
|
this.goodsImgH = goodsImgH.height / 2;
|
|
// 二维码图片高度
|
|
const ewmImgH = await this.getImageInfo(this.IMG_URL_SHARE+this.ewmImg);
|
|
this.ewmImgH = ewmImgH.height/ 2;
|
|
// 获取文字的宽度 本网价
|
|
this.price_new = '本网价' + this.price + "元"
|
|
this.price_old = '市场价' + this.Oldprice + "元"
|
|
// const price_new = await this.getImageInfo(this.price_new);
|
|
// const price_newW = price_new.width
|
|
|
|
// 设置画布的宽高
|
|
this.canvasW = this.SystemInfo.windowWidth; // 画布宽度等于设备宽度
|
|
// nameURLH.height
|
|
this.canvasH = (+ goodsImgH.height + pageTitleImgH.height + ewmImgH.height + 90 + 120) /
|
|
2; // 画布高度 = 推荐人头像高度 主图高度 + 页面标题高度 +二维码高度 + 文字图片的间距(大概50 不止等会调整)+ 于底部的距离
|
|
// this.canvasH = goodsImgH.height + pageTitleImgH.height + ewmImgH.height+ ewmImgH.height + 50; // 画布高度 = 主图高度 + 页面标题高度 +二维码高度 + 文字图片的间距(大概50 不止等会调整)
|
|
// 开始画画
|
|
if(goodsImgH.errMsg == 'getImageInfo:ok'
|
|
&& pageTitleImgH.errMsg == 'getImageInfo:ok'
|
|
&& ewmImgH.errMsg == 'getImageInfo:ok'
|
|
&& this.SystemInfo){
|
|
setTimeout(() => {
|
|
var ctx = uni.createCanvasContext('myCanvas', this);
|
|
// 填充背景色,白色
|
|
ctx.setFillStyle('#fff'); // 默认白色
|
|
ctx.fillRect(0, 0, this.canvasW, this.canvasH) // fillRect(x,y,宽度,高度)
|
|
// ctx.fillRect(0, 0, this.canvasW, ) // fillRect(x,y,宽度,高度)
|
|
|
|
// 绘制页面标题主图
|
|
ctx.drawImage(pageTitleImgH.path, 0, 0, this.canvasW, this.pageTitleImgH) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
|
|
|
|
|
// 绘制页面标题文字
|
|
ctx.setFontSize(16) // 字号
|
|
ctx.setFillStyle('#fff') // 颜色
|
|
ctx.font = 'normal bold 18px sans-serif'
|
|
ctx.fillText(this.pagesTitle, 120, 32); // (文字,x,y)
|
|
ctx.font = 'normal 18px sans-serif'
|
|
// 绘制 用户头像
|
|
// drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
|
ctx.drawImage(nameURLH.path, 17.5, this.pageTitleImgH + 7, this.nameURLW, this.nameURLH)
|
|
|
|
// ctx.arc(图片宽度+图片X,图片高度+图片Y, 图片宽,0, Math.PI * 2, false) 画圆 clip()裁切
|
|
// ctx.arc( 17.5, 7 + this.pageTitleImgH, this.nameURLW/2, 0, Math.PI * 2, false);
|
|
// ctx.clip();
|
|
// 绘制 文字
|
|
ctx.setFontSize(14)
|
|
ctx.setFillStyle('#000')
|
|
ctx.fillText('我是 ' + this.name, this.nameURLW + 20, this.nameURLH + 12);
|
|
// 绘制 文字
|
|
ctx.setFontSize(13)
|
|
ctx.setFillStyle('#707070')
|
|
ctx.fillText(this.alt, this.nameURLW + 20, this.nameURLH + 30 + 12);
|
|
|
|
// 绘制商品主图
|
|
ctx.drawImage(goodsImgH.path, 0, this.pageTitleImgH + this.nameURLH + 17, this.canvasW, this.goodsImgH) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
|
|
|
//4、商品价格
|
|
ctx.setFontSize(18) // 字号
|
|
ctx.setFillStyle('#DB0618') // 颜色
|
|
ctx.fillText(this.price_new, 10, this.pageTitleImgH + this.nameURLH + 34 + this.goodsImgH +10 + 30); // (文字,x,y)
|
|
// 价格划横线
|
|
ctx.beginPath()
|
|
const text_w = ctx.measureText('市场价' + this.Oldprice + "元").width + 30
|
|
ctx.setFontSize(12)
|
|
ctx.setFillStyle('#707070')
|
|
ctx.fillText('市场价' + this.Oldprice + "元", (this.price_new.length+1)*12 + 10+20, this.pageTitleImgH + this.nameURLH + 34 + this.goodsImgH +10 +30);
|
|
ctx.rect((this.price_new.length+1)*12 + 10+20, this.pageTitleImgH + this.nameURLH + 28.5 + this.goodsImgH +10 +30, this.price_old.length * 9 , 1)
|
|
ctx.fill()
|
|
ctx.closePath()
|
|
// 3、绘制商品标题,多余文字自动换行
|
|
ctx.setFontSize(16); // setFontSize() 设置字体字号
|
|
ctx.setFillStyle('#333'); // setFillStyle() 设置字体颜色
|
|
|
|
/* str 这段代码是我百度找的,参考别人的。canvas不能自动换行,需要自行计算 */
|
|
let _strlineW = 0;
|
|
let _strLastIndex = 0; //每次开始截取的字符串的索引
|
|
let _strHeight = this.pageTitleImgH + this.nameURLH +34 + this.goodsImgH +
|
|
25 +10 +30; //绘制字体距离canvas顶部的初始高度
|
|
let _num = 1;
|
|
for (let i = 0; i < this.title.length; i++) {
|
|
_strlineW += ctx.measureText(this.title[i]).width;
|
|
if (_strlineW > this.canvasW - 155) {
|
|
if (_num == 2 && 2) {
|
|
//文字换行数量大于二进行省略号处理
|
|
ctx.fillText(this.title.substring(_strLastIndex, i - 5) + '...', 10, _strHeight);
|
|
_strlineW = 0;
|
|
_strLastIndex = i;
|
|
_num++;
|
|
break;
|
|
} else {
|
|
ctx.fillText(this.title.substring(_strLastIndex, i), 10, _strHeight);
|
|
_strlineW = 0;
|
|
_strHeight += 20;
|
|
_strLastIndex = i;
|
|
_num++;
|
|
}
|
|
} else if (i == this.title.length - 1) {
|
|
ctx.fillText(this.title.substring(_strLastIndex, i + 1), 10, _strHeight);
|
|
_strlineW = 0;
|
|
}
|
|
}
|
|
|
|
// 绘制 二维码
|
|
// drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
|
ctx.drawImage(ewmImgH.path, uni.upx2px(530), this.pageTitleImgH + this.nameURLH + uni.upx2px(58) + this.goodsImgH, ewmImgH.width/3, ewmImgH.height/3)
|
|
|
|
ctx.draw(true, () => { // draw方法 把以上内容画到 canvas 中。
|
|
// console.log(ret,12311123132)
|
|
uni.showToast({
|
|
icon: 'success',
|
|
mask: true,
|
|
title: '绘制完成',
|
|
});
|
|
|
|
}, this);
|
|
}, 1500)
|
|
}else{
|
|
this.$Toast('海报生成失败')
|
|
}
|
|
},
|
|
methods: {
|
|
// 获取设备信息
|
|
getSystemInfo() {
|
|
return new Promise((req, rej) => {
|
|
uni.getSystemInfo({
|
|
success: function(res) {
|
|
req(res)
|
|
}
|
|
});
|
|
})
|
|
},
|
|
|
|
// 获取图片的高度
|
|
getImageInfo(image) {
|
|
// console.log(image)
|
|
return new Promise((req, rej) => {
|
|
uni.getImageInfo({
|
|
src: image,
|
|
success: function(res) {
|
|
req(res)
|
|
},
|
|
});
|
|
})
|
|
},
|
|
|
|
|
|
// 保存图片
|
|
saveImg_btn() {
|
|
var that = this
|
|
uni.canvasToTempFilePath({
|
|
canvasId: 'myCanvas',
|
|
// width: this.width * 3,
|
|
// height: this.height * 3,
|
|
// destWidth: this.width * 3,
|
|
// destHeight: this.height * 3,
|
|
quality: 1,
|
|
complete: (res) => {
|
|
// console.log('保存到相册', res);
|
|
uni.saveImageToPhotosAlbum({
|
|
filePath: res.tempFilePath,
|
|
success(res) {
|
|
uni.showToast({
|
|
title: '已保存到相册',
|
|
icon: 'success',
|
|
duration: 2000
|
|
})
|
|
setTimeout(() => {
|
|
that.isShow = false
|
|
}, 2000)
|
|
}
|
|
})
|
|
}
|
|
}, this);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.pages {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: #F5F5F5;
|
|
padding-bottom: 129rpx;
|
|
// 按钮
|
|
.btn {
|
|
position: fixed;
|
|
bottom: 0;
|
|
display: flex;
|
|
width: 100%;
|
|
height: 129rpx;
|
|
margin-top: 15rpx;
|
|
background-color: #fff;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
.btn_save {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: #01AEEA;
|
|
display: block;
|
|
width: 591rpx;
|
|
height: 88rpx;
|
|
border-radius: 38rpx;
|
|
color: #fff;
|
|
font-size: 36rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|