dl_uniapp/components/hj-placard/shareImages.vue

196 lines
4.9 KiB
Vue
Raw Permalink Normal View History

2025-03-31 14:31:41 +08:00
<template>
<view style="position: fixed;z-index: -9999;">
<canvas :canvas-id="canvasID" :style="{width:canvasWidth+'px',height:canvasHeight+'px'}"></canvas>
<view v-if="qrCode == ''">
<QRCode ref="qrcode" />
</view>
</view>
</template>
<script>
import QRCode from "@/components/qr_code/qrcode.vue"
var _this;
export default {
name: 'canvas-images',
props: {
// canvasID 等同于 canvas-id
canvasID: {
Type: String,
default: 'shareCanvas'
},
canvasWidth: { // 画布宽度
Type: 'int',
default: 375
},
canvasHeight: { // 画布高度
Type: 'int',
default: 500
},
shareTitle: { // 分享标题
Type: 'String',
default: '我是这张图片的标题'
},
goodsTitle: { // 商品宣传标题
Type: 'String',
default: '我是这张图片的标题我是这张图片的标题我是这张图片的标'
},
shareImage: { // 分享图片
Type: 'String',
default: '/static/bg.jpg'
},
qrSize: { // 二维码大小
Type: 'int',
default: 100
},
qrUrl: { // 生成二维码的链接
Type: 'String',
default: 'https://ext.dcloud.net.cn/plugin?id=5747'
}
},
components: {
QRCode
},
data() {
return {
qrCode: '', // 二维码
}
},
mounted() {
_this = this;
},
methods: {
// 创建二维码
canvasCreate() {
_this.$refs.qrcode.make({
size: _this.qrSize,
text: _this.qrUrl
})
.then(res => {
// 返回的res与uni.canvasToTempFilePath返回一致
// console.log(res)
_this.qrCode = res.tempFilePath;
_this.onCanvas();
});
},
// 画图
async onCanvas() {
uni.showLoading({
title: "分享图片生成中..."
});
const ctx = uni.createCanvasContext(_this.canvasID, _this);
// 设置 canvas 背景色
ctx.setFillStyle('#FFFFFF');
ctx.fillRect(0, 0, _this.canvasWidth, _this.canvasHeight);
ctx.setFillStyle('#000000');
// 背景图片
ctx.drawImage(_this.shareImage, 50, 50);
ctx.setFontSize(18);
ctx.setTextAlign('center');
ctx.fillText(_this.shareTitle, _this.canvasWidth / 2, 30);
// 左边标题
ctx.setTextAlign('left')
ctx.setFontSize(16)
_this.writeTextOnCanvas(ctx, 30, 21, _this.goodsTitle, 50, 350);
// 设置虚线
ctx.setStrokeStyle('#333333');
ctx.setLineDash([5, 10], 2);
ctx.beginPath();
ctx.moveTo(220, 340);
ctx.lineTo(220, 420);
ctx.stroke();
// 二维码
ctx.drawImage(_this.qrCode, 225, 330, 100, 100);
// ctx.draw();
// 延迟后渲染至canvas上
let pic = await _this.setTime(ctx)
_this.$emit('success', pic);
},
/**
* @param {Object} ctx_2d getContext("2d") 对象
* @param {int} lineheight 段落文本行高
* @param {int} bytelength 设置单字节文字一行内的数量
* @param {string} text 写入画面的段落文本
* @param {int} startleft 开始绘制文本的 x 坐标位置相对于画布
* @param {int} starttop 开始绘制文本的 y 坐标位置相对于画布
*/
writeTextOnCanvas(ctx_2d, lineheight, bytelength, text, startleft, starttop) {
// 获取字符串的真实长度(字节长度)
function getTrueLength(str) {
var len = str.length,
truelen = 0;
for (var x = 0; x < len; x++) {
if (str.charCodeAt(x) > 128) {
truelen += 2;
} else {
truelen += 1;
}
}
return truelen;
}
// 按字节长度截取字符串返回substr截取位置
function cutString(str, leng) {
var len = str.length,
tlen = len,
nlen = 0;
for (var x = 0; x < len; x++) {
if (str.charCodeAt(x) > 128) {
if (nlen + 2 < leng) {
nlen += 2;
} else {
tlen = x;
break;
}
} else {
if (nlen + 1 < leng) {
nlen += 1;
} else {
tlen = x;
break;
}
}
}
return tlen;
}
for (var i = 1; getTrueLength(text) > 0; i++) {
var tl = cutString(text, bytelength);
ctx_2d.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), startleft, (i - 1) * lineheight +
starttop);
text = text.substr(tl);
}
},
// 彻底改成同步 防止拿到的图片地址为空
setTime(ctx) {
return new Promise((resole, err) => {
setTimeout(() => {
ctx.draw(false, async () => {
let pic = await _this.getNewPic();
resole(pic)
});
}, 600)
})
},
// 获取新的图片地址
getNewPic() {
return new Promise((resolve, errs) => {
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: _this.canvasID,
quality: 1,
complete: (res) => {
// 在H5平台下tempFilePath 为 base64
// 关闭showLoading
uni.hideLoading();
// 储存海报地址 也是分享的地址
resolve(res.tempFilePath)
}
}, _this);
}, 200)
})
},
},
mounted() {
_this = this;
}
}
</script>