1、安装
cnpm i vue-canvas-poster --save
2、使用
<template>
<div class="share wh100">
<navBar title="邀请好友" :leftArrowFlag="true" />
<div class="content">
<h2>邀请亲友加入亲友团</h2>
<p>
邀请亲友加入后,可与您一起编写逝者生平故事,留言、上传照片、跟您一起完善逝者信息、共同缅怀
</p>
<div class="share_item">
<h3>方法一:长按海报发送朋友邀请加入</h3>
<div class="item_content">
<vue-canvas-poster
:widthPixels="1000"
:painting="painting"
@success="success"
@fail="fail"
></vue-canvas-poster>
<div class="poster_box">
<img v-if="showPoster" class="poster_img" :src="detail.posterImg" alt="" />
</div>
</div>
</div>
<div class="share_item">
<h3>方法二:点击发送链接邀请亲朋加入</h3>
<div class="item_content">
<div class="large_btn" @click="wxShare"><span>点击发送链接邀请亲朋加入</span></div>
</div>
</div>
</div>
<van-overlay class="overlay_box" :show="show" @click="show = false">
<div class="mask_content" @click="show = false">
<img class="arrow" src="http://****/files/app/download/pic/arrow.png" alt="">
<div class="mask_main">
<div class="main_item">
<div class="item_tip"><span>1</span></div>
<div class="item_test">
<span>点击右上角</span>
<div class="item_btn">
<span>. . .</span>
</div>
<span>按钮</span>
</div>
</div>
<div class="main_item">
<div class="item_tip"><span>2</span></div>
<div class="item_test">
<span>将本页面分享给好友</span>
</div>
</div>
</div>
</div>
</van-overlay>
</div>
</template>
<script>
import navBar from "@/components/navBar";
import { VueCanvasPoster } from "vue-canvas-poster";
import sdk from "@/utils/wxShare"
import {getShareData} from '@/api/memorialHall'
export default {
data() {
return {
painting:null,
showPoster:false,
show:false,//显示隐藏
detail: {
posterImg:null
},
};
},
components: {
navBar,
VueCanvasPoster,
},
created() {
console.log(this.detail.posterImg, "分享");
this.getData(this.$route.params.id)
},
mounted() {
},
methods: {
async getData(id) {
let params={
id
}
let res= await getShareData(params)
console.log(res,'000')
if(res.code!='2000'){
this.$toast.fail(res.msg)
return
}
this.detail=res.data;
this.ininShare(res.data)
this.initPoster(res.data)
},
ininShare(data){
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
let obj={
title: `${data.deadName}的纪念馆`,
des:`${data. biography}`,
linkurl: `http://**************/memorialHall/${data.id}`,//分享链接
img: `${data.deadPortraitUrl}`,
}
// let url = encodeURIComponent(location.href.split('#')[0]);
let url = location.href.split('#')[0];
sdk.getJSSDK(url, obj)
}else{
}
},
initPoster(data){
this.painting = {
width: "275px",
height: "365px",
borderRadius: "5px",
background: `${data.captionUrl}`,
views: [
{
type: "image",
url: `${data.deadPortraitUrl}`,
css: {
top: "20px",
left: "107.5px",
borderRadius: "30px",
width: "60px",
height: "60px",
},
},
{
type: "text",
text: `${data.deadName}的纪念馆`,
css: {
top: "90px",
fontSize: "14px",
left: "90px",
color: "#fff",
textAlign: "center",
},
},
{
type: "text",
text: `${data.birthday}-${data.deathday}`,
css: {
top: "110px",
fontSize: "14px",
left: "60px",
color: "#fff",
textAlign: "center",
},
},
{
type: "qrcode",
content: `http://****/memorialHall/${data.id}`,
css: {
background: "#fff",
padding: "10px",
width: "100px",
height: "100px",
left: "90px",
top: "170px",
borderWidth: "10px",
borderRadius: "1px",
borderColor: "#fff",
},
},
{
type: "text",
text: "扫码查看在线纪念馆",
css: {
bottom: "50px",
fontSize: "14px",
left: "80px",
color: "#fff",
textAlign: "center",
},
},
],
};
},
success(src) {
this.detail.posterImg = src;
this.showPoster=true
},
fail(err) {
console.log("fail", err);
},
wxShare(){
this.show=true
}
},
};
</script>
<style lang="scss" scoped>
.share {
display: flex;
flex-direction: column;
.content {
flex: 1;
padding: 0.12rem 0.37rem;
// background-color: #3e3e3e;
h2 {
font-size: 16px;
line-height: 0.23rem;
font-weight: 600;
margin-bottom: 0.07rem;
}
p {
font-size: 14px;
line-height: 0.2rem;
color: $lightBlack;
margin-bottom: 0.05rem;
}
.share_item {
margin-bottom: 0.1rem;
h3 {
font-size: 16px;
line-height: 0.23rem;
font-weight: 600;
margin-bottom: 0.07rem;
}
.item_content {
display: flex;
flex-direction: column;
align-items: center;
.poster_box {
width: 2.75rem;
height: 3.65rem;
img{
width: 100%;
height: 100%;
}
}
}
}
}
}
.overlay_box{
.mask_content{
padding:1rem 0.5rem;
font-size: 14px;
color: #fff;
}
.main_item{
display: flex;
align-items: center;
margin-bottom: 0.2rem;
}
.item_test{
display: flex;
align-items: center;
}
.item_tip{
width: 0.2rem;
height: 0.2rem;
border-radius: 50%;
background: crimson;
text-align: center;
line-height: 0.2rem;
margin-right: 0.15rem;
}
.item_btn{
padding:0.05rem 0.1rem;
text-align: center;
height: 0.3rem;
background: #282D32;
border-radius: 0.05rem;
margin:0 0.1rem;
}
.item_btn span{
line-height: 0.2rem;
}
.arrow{
position: absolute;
right:0.2rem;
top:0.2rem;
display: block;
width: 1rem;
z-index: 6;
}
}
</style>
wxShare.js
import {wxSignatureVerification} from '@/api/wx'
import {Toast} from 'vant'
//import wx from 'weixin-js-sdk';
import wx from 'weixin-jsapi';
//
//要用到微信API
function getJSSDK(url,shareData) {
let params={url}
console.log(wx,params,'url参数')
wxSignatureVerification(params).then(res => {
console.log('22222',res,shareData);
if(res.code!='2000')return Toast.fail('微信验签失败')
let result=res.data.wxConfig
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.data.appId, // 必填,公众号的唯一标识
timestamp: result.timestamp, // 必填,生成签名的时间戳
nonceStr: result.nonceStr, // 必填,生成签名的随机串
signature: result.signature, // 必填,签名
jsApiList:[
'onMenuShareTimeline',
'onMenuShareAppMessage'
]
})
wx.ready(function () {
//分享给微信朋友
wx.onMenuShareAppMessage({
title: shareData.title,
desc: shareData.des,
link: shareData.linkurl,
imgUrl: shareData.img,
success: function success(res) {
Toast.success('分享成功')
},
cancel: function cancel(res) {
console.log('已取消');
},
fail: function fail(res) {
//alert(JSON.stringify(res));
}
});
// 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
wx.onMenuShareTimeline({
title: shareData.title,
link: shareData.linkurl,
imgUrl: shareData.img,
success: function success(res) {
//alert('已分享');
},
cancel: function cancel(res) {
//alert('已取消');
},
fail: function fail(res) {
//alert(JSON.stringify(res));
}
});
// 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口
// wx.onMenuShareQQ({
// title: shareData.title,
// desc: shareData.desc,
// link: shareData.linkurl,
// imgUrl: shareData.img,
// trigger: function trigger(res) {
// //alert('用户点击分享到QQ');
// },
// complete: function complete(res) {
// alert(JSON.stringify(res));
// },
// success: function success(res) {
// //alert('已分享');
// },
// cancel: function cancel(res) {
// //alert('已取消');
// },
// fail: function fail(res) {
// //alert(JSON.stringify(res));
// }
// });
// 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口
// wx.onMenuShareWeibo({
// title: shareData.title,
// desc: shareData.desc,
// link: shareData.linkurl,
// imgUrl: shareData.img,
// trigger: function trigger(res) {
// //alert('用户点击分享到微博');
// },
// complete: function complete(res) {
// // alert(JSON.stringify(res));
// },
// success: function success(res) {
// //alert('已分享');
// },
// cancel: function cancel(res) {
// // alert('已取消');
// },
// fail: function fail(res) {
// // alert(JSON.stringify(res));
// }
// });
})
wx.error(function (res) {
//alert("微信验证失败");
});
})
}
export default {
// 获取JSSDK
getJSSDK
}
备注
该方案生成的海报二维码在IOS上扫描报错,所以更改方案 :生成二维码图片之后在用二维码图片绘制到海报上生成海报
更改后代码:
<template>
<div class="share wh100">
<navBar title="邀请好友" :leftArrowFlag="true" />
<div class="content">
<h2>邀请亲友加入亲友团</h2>
<p>
邀请亲友加入后,可与您一起编写逝者生平故事,留言、上传照片、跟您一起完善逝者信息、共同缅怀
</p>
<div class="share_item">
<h3>方法一:长按海报发送朋友邀请加入</h3>
<div class="item_content">
<vue-canvas-poster
:widthPixels="1000"
:painting="painting"
@success="success"
@fail="fail"
></vue-canvas-poster>
<div class="poster_box">
<img
v-if="showPoster"
class="poster_img"
:src="detail.posterImg"
alt=""
/>
</div>
</div>
</div>
<div class="share_item">
<h3>方法二:点击发送链接邀请亲朋加入</h3>
<div class="item_content">
<div class="large_btn" @click="wxShare">
<span>点击发送链接邀请亲朋加入</span>
</div>
</div>
</div>
</div>
<van-overlay class="overlay_box" :show="show" @click="show = false">
<div class="mask_content" @click="show = false">
<img
class="arrow"
src="http://linyiapi.fushoubainian.com/files/app/download/pic/arrow.png"
alt=""
/>
<div class="mask_main">
<div class="main_item">
<div class="item_tip"><span>1</span></div>
<div class="item_test">
<span>点击右上角</span>
<div class="item_btn">
<span>. . .</span>
</div>
<span>按钮</span>
</div>
</div>
<div class="main_item">
<div class="item_tip"><span>2</span></div>
<div class="item_test">
<span>将本页面分享给好友</span>
</div>
</div>
</div>
</div>
</van-overlay>
<div id="qrcode"></div>
</div>
</template>
<script>
import navBar from "@/components/navBar";
import { VueCanvasPoster } from "vue-canvas-poster";
import sdk from "@/utils/wxShare";
import { getShareData } from "@/api/memorialHall";
import QRCode from "qrcodejs2";
export default {
data() {
return {
loading: null,
painting: null,
qrcode: "", //二维码
defaultAvatar: require("@/assets/imgs/avatar.png"),
showPoster: false,
show: false, //显示隐藏
detail: {
posterImg: null,
},
};
},
components: {
navBar,
VueCanvasPoster,
},
created() {
console.log(this.detail.posterImg, "分享");
this.getData(this.$route.params.id);
},
mounted() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
var u = navigator.userAgent,
app = navigator.appVersion;
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isIOS) {
if (window.location.href.indexOf("#reloaded") == -1) {
window.location.href = window.location.href + "#reloaded";
window.location.reload();
}
}
}
},
methods: {
getCodeSrc(link) {
return new Promise((resolve, reject) => {
document.getElementById("qrcode").innerHTML = "";
this.qrcode = new QRCode("qrcode", {
width: 124,
height: 124, // 高度
text: link, // 二维码内容
// render: 'canvas' , // 设置渲染方式(有两种方式 table和canvas,默认是canvas)
// background: '#f0f', // 背景色
// foreground: '#ff0' // 前景色
});
console.log(this.qrcode, "kkkk");
var canvas = this.qrcode._oDrawing._elCanvas;
//如果有循环,此句必不可少 qrcode.find('canvas').remove();
var src = canvas.toDataURL("image/jpg");
resolve(src);
});
},
async getData(id) {
let params = {
id,
};
let res = await getShareData(params);
if (res.code != "2000") {
this.$toast.fail(res.msg || "数据请求失败");
return;
}
this.detail = res.data;
this.initPoster(res.data);
},
ininShare(data) {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
let obj = {
title: `${data.deadName}的纪念馆`,
des: `${data.biography}`,
linkurl: `http://*****/memorialHall/${data.id}`, //分享链接
img: `${data.deadPortraitUrl}`,
};
// let url = encodeURIComponent(location.href.split('#')[0]);
let url = location.href.split("#")[0];
sdk.getJSSDK(url, obj);
} else {
}
},
initPoster(data) {
this.loading = this.$toast.loading({
message: "加载中...",
forbidClick: true,
});
this.getCodeSrc(
`http://*****/memorialHall/${data.id}`
).then((res) => {
this.painting = {
width: "300px",
height: "400px",
borderRadius: "5px",
background: `${data.captionUrl}`,
views: [
{
type: "image",
url: data.deadPortraitUrl
? `${data.deadPortraitUrl}`
: this.defaultAvatar,
css: {
top: "20px",
left: "120px",
borderRadius: "30px",
width: "60px",
height: "60px",
},
},
{
type: "text",
text: `${data.deadName}的纪念馆`,
css: {
top: "90px",
fontSize: "14px",
left: "105px",
color: "#fff",
textAlign: "center",
},
},
{
type: "text",
text: `${data.birthday}—${data.deathday}`,
css: {
top: "120px",
fontSize: "14px",
left: "70px",
color: "#fff",
textAlign: "center",
},
},
{
type: "image",
url: res,
css: {
background: "#fff",
top: "250px",
left: "100px",
width: "100px",
height: "100px",
borderWidth: "6px",
borderRadius: "1px",
borderColor: "#fff",
},
},
// {
// type: "qrcode",
// content: `http://****/memorialHall/${data.id}`,
// css: {
// background: "#fff",
// width: "100px",
// height: "100px",
// left: "100px",
// top: "210px",
// borderWidth: "10px",
// borderRadius: "1px",
// borderColor: "#fff",
// },
// },
{
type: "text",
text: "扫码查看在线纪念馆",
css: {
bottom: "20px",
fontSize: "14px",
left: "90px",
color: "#fff",
textAlign: "center",
},
},
],
};
});
},
success(src) {
console.log(src, "哈哈哈哈");
this.$toast.clear();
this.detail.posterImg = src;
this.showPoster = true;
},
fail(err) {
console.log("fail", err);
},
wxShare() {
this.show = true;
},
},
};
</script>
<style lang="scss" scoped>
.share {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
#qrcode {
display: none;
}
.content {
flex: 1;
padding: 0.05rem 0.37rem;
// background-color: #3e3e3e;
overflow-y: scroll;
h2 {
font-size: 14px;
line-height: 0.2rem;
font-weight: 600;
margin-bottom: 0.07rem;
}
p {
font-size: 14px;
line-height: 0.2rem;
color: $lightBlack;
margin-bottom: 0.05rem;
}
.share_item {
margin-bottom: 0.1rem;
h3 {
font-size: 14px;
line-height: 0.2rem;
font-weight: 600;
margin-bottom: 0.07rem;
}
.item_content {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
-moz-align-items: center;
-webkit-align-items: center;
align-items: center;
.poster_box {
width: 3rem;
height: 4rem;
img {
width: 100%;
height: 100%;
}
}
}
}
}
}
.overlay_box {
.mask_content {
padding: 1rem 0.5rem;
font-size: 14px;
color: #fff;
}
.main_item {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-align-items: center;
-webkit-align-items: center;
align-items: center;
margin-bottom: 0.2rem;
}
.item_test {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-align-items: center;
-webkit-align-items: center;
align-items: center;
}
.item_tip {
width: 0.2rem;
height: 0.2rem;
border-radius: 50%;
background: crimson;
text-align: center;
line-height: 0.2rem;
margin-right: 0.15rem;
}
.item_btn {
padding: 0.05rem 0.1rem;
text-align: center;
height: 0.3rem;
background: #282d32;
border-radius: 0.05rem;
margin: 0 0.1rem;
}
.item_btn span {
line-height: 0.2rem;
}
.arrow {
position: absolute;
right: 0.2rem;
top: 0.2rem;
display: block;
width: 1rem;
z-index: 6;
}
}
</style>
图片跨域
1.如果图片在你自己的服务器上,配置 nginx
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Credentials "true";
if ($request_method = "OPTIONS") {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
return 204;
}
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
add_header Access-Control-Allow-Origin *;
expires 30d;
error_log off;
access_log /dev/null;
}