耀实惠小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

307 lines
10 KiB

<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>