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