277 lines
7.4 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 分享海报 -->
<view class="share" @click="closeShow" catchtouchmove="preventD">
<view class="box" v-show="!showPrivacy">
<canvas class="canvas" id="myCanvas" canvas-id="myCanvas" @click.stop></canvas>
<view class="btn" @tap.stop="saveImage">保存图片</view>
</view>
</view>
<!-- 隐私协议弹窗 -->
<privacy-popup :show-dialog="showPrivacy" @close="showPrivacy = false" @agree.stop="showPrivacy = false" @refuse="showPrivacy = false" />
</template>
<script>
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
import { getOldDay, saveImg, judgePrivacy, showToast } from '../common.js'
import { post } from '@/api/request.js'
import api from '@/api/index.js'
import privacyPopup from '../privacyPopup/index.vue'
export default {
components: {
privacyPopup
},
props: {
goods: Object
},
setup(props, context) {
const data = reactive({
canvasWidth: {},
ctx: null,
showImage: '',
avatar: '',
faceImg: '',
loading: false,
shareImg: '',
Color: uni.getStorageSync('theme_color'),
showPrivacy: false
})
// 关闭
function closeShow() {
context.emit('closeShow')
}
function draw1() {
data.ctx.setFontSize(20)
data.ctx.setFillStyle('white')
data.ctx.fillRect(0, 0, data.canvasWidth.width || 275, data.canvasWidth.height || 470)
data.ctx.drawImage(data.avatar, 15, 10, 30, 30)
data.ctx.setFontSize(12)
data.ctx.setFillStyle('#666666')
var nickname = uni.getStorageSync('nickname')
data.ctx.fillText(nickname, 50, 20)
data.ctx.setFontSize(11)
data.ctx.setFillStyle('#999999')
data.ctx.fillText(getOldDay(), 50, 40)
data.ctx.drawImage(data.faceImg, 15, 50, 245, 245)
data.ctx.font = 'warp bold 15px Arial,sans-serif '
data.ctx.setFillStyle('#111111')
toFormateStr(data.ctx, props.goods.title, 15, 315, 15, 230, 1)
data.ctx.setFontSize(12)
data.ctx.setFillStyle('#999999')
toFormateStr(data.ctx, props.goods.description.replace(/\s+/g, ''), 15, 335, 15, 230, 3)
data.ctx.setFontSize(12)
data.ctx.setFillStyle('#F14939')
let price = ''
if (props.goods.goods_size > 1) {
if (parseInt(props.goods.max_price) < parseInt(props.goods.min_price)) {
price = props.goods.max_price + '~' + props.goods.min_price
} else {
price = props.goods.min_price + '~' + props.goods.max_price
}
} else {
if (props.goods.group_goods[0].specs_type === 0) {
price = props.goods.group_goods[0].price
} else {
if (props.goods.group_goods[0].max_price === props.goods.group_goods[0].min_price) {
price = props.goods.group_goods[0].min_price
} else if (
parseInt(props.goods.group_goods[0].max_price) <
parseInt(props.goods.group_goods[0].min_price)
) {
price = props.goods.group_goods[0].max_price + '~' + props.goods.group_goods[0].min_price
} else {
price = props.goods.group_goods[0].min_price + '~' + props.goods.group_goods[0].max_price
}
}
}
data.ctx.fillText('¥', 15, 400)
data.ctx.setFontSize(15)
data.ctx.fillText(price, 27, 400)
data.ctx.setFillStyle('rgba(246, 246, 246, 0.9)')
data.ctx.fillRect(15, 410, 130, 55)
data.ctx.setFontSize(11)
data.ctx.setFillStyle('#999999')
data.ctx.fillText('长按识别图中小程序', 25, 430)
data.ctx.fillText('跟团购买>>', 25, 450)
data.ctx.drawImage(data.showImage, 165, 375, 90, 90)
data.ctx.draw()
}
// 文本换行
function toFormateStr(
ctx,
content,
drawX, // 15
drawY, // 335
lineHeight, // 15
lineMaxWidth, // 230
lineNum // 3
) {
var drawTxt = '' // 当前绘制的内容
var drawLine = 1 // 第几行开始绘制
var drawIndex = 0 // 当前绘制内容的索引
// 判断内容是否可以一行绘制完毕
if (ctx.measureText(content).width <= lineMaxWidth) {
ctx.fillText(content.substring(drawIndex, i), drawX, drawY)
} else {
for (var i = 0; i < content.length; i++) {
drawTxt += content[i]
if (ctx.measureText(drawTxt).width >= lineMaxWidth) {
if (drawLine >= lineNum) {
ctx.fillText(content.substring(drawIndex, i) + '..', drawX, drawY)
break
} else {
ctx.fillText(content.substring(drawIndex, i + 1), drawX, drawY)
drawIndex = i + 1
drawLine += 1
drawY += lineHeight
drawTxt = ''
}
} else {
// 内容绘制完毕但是剩下的内容宽度不到lineMaxWidth
if (i === content.length - 1) {
ctx.fillText(content.substring(drawIndex), drawX, drawY)
}
}
}
}
}
// 获取单张图片信息
const getImageInfo = async (imgSrc) => {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: imgSrc,
success: function(image) {
resolve(image.path)
},
fail(err) {
reject()
}
})
})
}
// 获取页面二维码
const getImg = () => {
return new Promise((resolve, reject) => {
uni.request({
url: api.url + '/api/v1/user/code',
method: 'POST',
data: {
page: 'pages/groups/index',
shop_goods_id: props.goods.id
},
header: {
Authorization: uni.getStorageSync('token') || '',
appid: api.appId
},
responseType: 'arraybuffer',
success: (res) => {
if (res.statusCode === 200) {
let base64 = ''
const bytes = new Uint8Array(res.data)
const len = bytes.byteLength
for (let i = 0; i < len; i++) {
base64 += String.fromCharCode(bytes[i])
}
base64 = `data:image/png;base64,${btoa(base64)}`
resolve(base64)
} else {
reject('')
}
},
})
})
}
onMounted(() => {
uni.showLoading({
mask: true,
title: '海报生成中...'
})
const instance = getCurrentInstance()
setTimeout(() => {
const query = uni.createSelectorQuery().in(instance)
query.select('#myCanvas').boundingClientRect(async (res) => {
console.log(res)
data.canvasWidth = res || {}
data.ctx = uni.createCanvasContext('myCanvas', instance)
data.avatar = await getImageInfo(uni.getStorageSync('avatar'))
data.faceImg = await getImageInfo(props.goods.face_img)
data.showImage = await getImg()
await draw1()
uni.hideLoading()
}).exec()
}, 200)
})
return {
...toRefs(data),
draw1,
closeShow,
getImg,
getImageInfo
}
},
methods: {
async saveImage() {
if(await judgePrivacy()) {
this.showPrivacy = true
return false
}
//保存到相册
const _this = this
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success(res) {
saveImg(res.tempFilePath)
},
fail(err) {
}
}, _this)
}
}
}
</script>
<style lang="scss" scoped>
.share {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba($color: #000000, $alpha: 0.7);
z-index: 202;
display: flex;
flex-direction: column;
justify-content: center;
.canvas {
width: 275px;
height: 470px;
box-sizing: border-box;
margin: 0 auto;
background-color: #fff;
}
.btn {
color: #fff;
background-color: v-bind('Color');
font-size: 30rpx;
width: 340rpx;
height: 76rpx;
line-height: 76rpx;
text-align: center;
margin: 60rpx auto 0;
border-radius: 76rpx;
}
}
</style>