前端页面代码
<template>
<div class="shareImg">
<!-- <Header :title="title"></Header> -->
<div class="share">
<img :src="image" class="img" alt="" />
<canvas id="mycanvas" class="my-canvas"></canvas>
</div>
<div class="tips flex-c-c" v-if="!show">
<span>(长按保存图片)</span>
</div>
<div class="m-t10" v-if="show">
<van-button type="info" @click="dowload">保存图片</van-button>
</div>
</div>
</template>
<script>
// import Header from "../components/Header";
import { itemextendQrcode } from "../api/Home";
export default {
data() {
return {
title: "分享图",
image: "",
QRcode: "",
item: {},
show: true
};
},
components: {
// Header
},
created() {
this.$LoadingToast("数据加载中");
if (this.$store.state.status.envType === "xcx") {
this.show = false;
}
if (this.$route.query.item) {
this.item = JSON.parse(this.$route.query.item);
}
},
mounted() {
this.itemextendQrcode();
},
methods: {
itemextendQrcode() {//调接口生成太阳码的二进制数据流,这个前端自己做不了,因为需要调用微信的接口,接口中有个参数存在有效期
let user = JSON.parse(localStorage.getItem("user"));
itemextendQrcode({
pageStr: "pages/toggleLogin/toggleLogin",
scene: `projectId=${this.item.id}&shareId=${user.uid}`
}).then(res => {
this.QRcode = `data:${res}`;
this.drawPhoto();
this.$clearToast();
});
},
dowload() {
let a = document.createElement("a");
let event = new MouseEvent("click");
a.download = "分享图.png";
a.href = this.image;
a.dispatchEvent(event);
},
drawtext(ctx, t, x, y, w) {
//参数说明
//ctx:canvas的 2d 对象,t:绘制的文字,x,y:文字坐标,w:文字最大宽度
let a = t.length > 28 ? t.slice(0, 28) + "..." : t;
let chr = a.split("");
let temp = "";
let row = [];
ctx.fillStyle = "#1989fa";
let multiple = (window.innerWidth / 375).toFixed(2);
let size = `${18 * multiple}px`;
ctx.font = `bold ${size} Arial`;
for (let a = 0; a < chr.length; a++) {
if (
ctx.measureText(temp).width < w &&
ctx.measureText(temp + chr[a]).width <= w
) {
temp += chr[a];
} else {
row.push(temp);
temp = chr[a];
}
}
row.push(temp);
for (let b = 0; b < row.length; b++) {
ctx.fillText(row[b], x, y + (b + 1) * 25 * multiple); //每行字体y坐标间隔20
}
},
drawPhoto: async function() {
let multiple = (window.innerWidth / 375).toFixed(2); // 考虑不同设备的尺寸,直接通过目标设备宽度和375px宽度的比例作为展示效果的放大或者缩小
const canvas = document.getElementById("mycanvas");
const context = canvas.getContext("2d");
const loadImage = src => {
return new Promise((resolve, reject) => {
const img = new Image();
img.setAttribute("crossOrigin", "anonymous");
img.onload = () => resolve(img);
img.onerror = error => reject(error);
img.src = src;
});
};
try {
const img1 = await loadImage(require("../assets/backShare.jpg"));
const img2 = await loadImage(this.QRcode);
const img3 = await loadImage(this.item.img);
canvas.setAttribute("width", 316 * multiple);
canvas.setAttribute("height", 560 * multiple);
context.fillStyle = "lightblue";
context.fillRect(0, 0, canvas.width, canvas.height);
context.drawImage(img1, 0, 0, canvas.width, canvas.height);
context.drawImage(
img2,
108 * multiple,
80 * multiple,
100 * multiple,
100 * multiple
);
context.drawImage(
img3,
40 * multiple,
230 * multiple,
236 * multiple,
236 * multiple
);
this.drawtext(
context,
this.item.name,
35 * multiple,
470 * multiple,
265 * multiple
);
this.image = canvas.toDataURL("image/jpg", 1.0);
} catch (error) {
console.error("图片加载失败", error);
}
}
}
};
</script>
<style lang="less" scoped>
.shareImg {
margin: 55px auto 0;
}
.tips {
color:
font-size: 14px;
}
.share {
width: 100%;
padding: 0px 30px;
}
.my-canvas {
background-color:
position: fixed;
top: 1000000px;
right: 10000px;
z-index: 1;
}
.img {
width: 100%;
height: auto;
}
border: 1px solid rgb(199, 198, 198);
}
</style>
小程序需要注意:同样传参是projectId = ‘12’,小程序的页面通过onShareAppMessage 分享和生成太阳码获取参数是不一样的
if(e.scene){//分享的小程序二维码,扫码进入
let scene = decodeURIComponent(e.scene)
let arr = scene.split("&")
projectId = arr[0].split("=")[1]
}else{ // 通过微信的分享朋友的卡片进入
projectId = e.projectId || ''
}