405 lines
11 KiB
Vue
405 lines
11 KiB
Vue
<script setup>
|
||
import { gsap } from "gsap";
|
||
import { debounceTap } from "@/plugins";
|
||
import { useMainStore } from "@/store";
|
||
|
||
import { Toast } from "vant";
|
||
import QRCode from "qrcode";
|
||
import { reactive } from "vue";
|
||
|
||
// 页面配置初始化
|
||
const emit = defineEmits(["ResultPage"]);
|
||
const userStore = useMainStore();
|
||
const posterId = ref(userStore.posterId); //海报背景id:1~11
|
||
|
||
console.log('海报id', posterId.value);
|
||
|
||
// 二维码坐标
|
||
const eqcodePosition = [
|
||
{w:750,h:2107,x: 527, y: 1882},
|
||
{w:750,h:2111,x: 529, y: 1873},
|
||
{w:750,h:2194,x: 527, y: 1973},
|
||
{w:750,h:2045,x: 527, y: 1824},
|
||
{w:750,h:2194,x: 527, y: 1979},
|
||
]
|
||
|
||
const posterImgList = reactive([
|
||
new URL(`../assets/images/result/poster-1.jpg`, import.meta.url).href,
|
||
new URL(`../assets/images/result/poster-2.jpg`, import.meta.url).href,
|
||
new URL(`../assets/images/result/poster-3.jpg`, import.meta.url).href,
|
||
new URL(`../assets/images/result/poster-4.jpg`, import.meta.url).href,
|
||
new URL(`../assets/images/result/poster-5.jpg`, import.meta.url).href,
|
||
|
||
])
|
||
|
||
// 生成二维码逻辑
|
||
const eqcodePic = ref();
|
||
onMounted(async () => {
|
||
|
||
// 执行任务队列
|
||
await executeTasks();
|
||
|
||
});
|
||
|
||
|
||
// 这是新加的函数封装异步任务
|
||
const executeTasks = async () => {
|
||
console.log("二维码生成中...");
|
||
|
||
// 生成二维码
|
||
const eqCodeUrl = import.meta.env.VITE_URL;
|
||
eqcodePic.value = await QRCode.toDataURL(eqCodeUrl);
|
||
|
||
console.log("生成海报中...");
|
||
|
||
// 生成海报
|
||
console.log('pid', posterImgList[posterId.value - 1]);
|
||
|
||
|
||
if (posterImgList[posterId.value - 1] && eqcodePic.value) {
|
||
|
||
posterCreate(
|
||
{ width: 750, height: eqcodePosition[posterId.value-1].h },
|
||
[
|
||
{ name: "bg", src: posterImgList[posterId.value - 1], pos: { w: 750, h: eqcodePosition[posterId.value-1].h, x: 0, y: 0 } },
|
||
{ name: "eqcode", src: eqcodePic.value, pos: { w: 187, h: 187, x: eqcodePosition[posterId.value-1].x, y: eqcodePosition[posterId.value-1].y } },
|
||
]
|
||
);
|
||
} else {
|
||
Toast.fail({ message: '生成失败' })
|
||
emit("ResultPage", { action: 'hide' })
|
||
}
|
||
|
||
};
|
||
|
||
|
||
const showPoster = () => {
|
||
gsap.to(".posterPop", {
|
||
duration: 0.3,
|
||
autoAlpha: 1,
|
||
});
|
||
gsap.from(".cls-btn-box", {
|
||
duration: 0.7,
|
||
scale: 1.2,
|
||
autoAlpha: 0,
|
||
});
|
||
gsap.from(".poster-box", {
|
||
duration: 0.7,
|
||
scale: 0.6,
|
||
autoAlpha: 0,
|
||
});
|
||
gsap.from(".save-tips", {
|
||
duration: 0.7,
|
||
scale: 0.7,
|
||
autoAlpha: 0,
|
||
delay: 0.3
|
||
});
|
||
gsap.from(".go-draw", {
|
||
duration: 0.7,
|
||
y: -30,
|
||
autoAlpha: 0,
|
||
delay: 0.5
|
||
});
|
||
gsap.from(".go-share", {
|
||
duration: 0.7,
|
||
y: -30,
|
||
autoAlpha: 0,
|
||
delay: 0.7
|
||
});
|
||
|
||
}
|
||
|
||
|
||
// 去抽奖
|
||
const goDraw = (event) => {
|
||
let e = event.target;
|
||
debounceTap(e, () => {
|
||
if (userStore.hasDraw) {
|
||
emit("ResultPage", { action: "showDraw" });
|
||
} else {
|
||
Toast("今日暂无抽奖机会");
|
||
}
|
||
});
|
||
};
|
||
|
||
// 隐藏海报弹窗
|
||
const hidePop = (event) => {
|
||
let e = event.target;
|
||
debounceTap(e, () => {
|
||
gsap.to(".posterPop", {
|
||
duration: 0.5, autoAlpha: 0,
|
||
onComplete: () => {
|
||
emit('ResultPage', { action: 'hide' })
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
const hide =(event)=>{
|
||
let e = event.target;
|
||
debounceTap(e, () => {
|
||
gsap.to(".posterPop", {
|
||
duration: 0.5, autoAlpha: 0,
|
||
onComplete: () => {
|
||
emit('ResultPage', { action: 'showQuestion' })
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
|
||
// 展示分享
|
||
const goShare = (event) => {
|
||
let e = event.target;
|
||
debounceTap(e, () => {
|
||
gsap.to(".sharePop", { duration: 0.5, autoAlpha: 1 });
|
||
});
|
||
};
|
||
|
||
// 隐藏分享提示
|
||
const hideShare = () => {
|
||
gsap.to(".sharePop", { duration: 0.5, autoAlpha: 0 });
|
||
};
|
||
|
||
|
||
|
||
// 海报生成
|
||
const posterCreate = (option, imageArr) => {
|
||
let posterUrl = ''
|
||
const { width, height } = option
|
||
Toast.loading({
|
||
message: '海报生成中',
|
||
duration: 0,
|
||
forbidClick: true
|
||
})
|
||
|
||
|
||
let mycanvas = document.createElement('canvas') // 创建一个canvas画布元素
|
||
let ctx = mycanvas.getContext('2d')
|
||
mycanvas.style.width = `${width}px`; //设置canvas的宽
|
||
mycanvas.style.height = `${height}px`; //设置canvas的高
|
||
mycanvas.width = width
|
||
mycanvas.height = height
|
||
//Promise对象加载资源
|
||
let loader_p = [];
|
||
imageArr.map((item) => {
|
||
const _p = new Promise(resolve => {
|
||
const img = new Image();
|
||
img.crossOrigin = 'Anonymous'
|
||
img.onload = () => {
|
||
resolve(img)
|
||
};
|
||
img.src = item.src;
|
||
});
|
||
loader_p.push(_p);
|
||
})
|
||
//Promise的.all方法,当所有预加载的图像加载好的回调函数
|
||
Promise.all(loader_p)
|
||
.then(imgList => {
|
||
console.log('imgList', imgList);
|
||
|
||
// 图片素材遍历绘制
|
||
imgList.map((item, index) => {
|
||
ctx.drawImage(item, imageArr[index].pos.x, imageArr[index].pos.y, imageArr[index].pos.w, imageArr[index].pos.h); //原生canvas的绘制图片方法,直接百度搜索 `js drawImage`查看方法的参数
|
||
})
|
||
|
||
//海报绘制完 ,转成图片对象
|
||
return mycanvas.toDataURL('image/jpeg', 1);
|
||
})
|
||
.then(baseURL => {
|
||
//返回的图片地址,就是最后海报的地址,可以放在DOM显示
|
||
let posterImg = document.querySelector('#posterSrc')
|
||
posterImg.src = baseURL
|
||
setTimeout(() => {
|
||
// 展示海报
|
||
showPoster();
|
||
Toast.success({ message: '生成成功!' })
|
||
|
||
}, 500)
|
||
})
|
||
.catch(error => {
|
||
console.error("生成海报失败");
|
||
gsap.to(".posterPop", {
|
||
duration: 0.5,
|
||
autoAlpha: 0,
|
||
onComplete: () => {
|
||
emit('ResultPage', { action: 'hide' })
|
||
}
|
||
});
|
||
Toast.fail({ message: '生成失败,请重试!' });
|
||
});
|
||
|
||
// return posterUrl
|
||
}
|
||
|
||
</script>
|
||
|
||
<template>
|
||
<div class="posterPop" @touchmove.prevent>
|
||
<div class="poster-bg"></div>
|
||
<div class="poster-container">
|
||
<div class="cls-btn-box">
|
||
<div class="cls-btn" @click="hidePop($event)"></div>
|
||
</div>
|
||
<div class="poster-box" :class="'poster-box-' + posterId">
|
||
<div class="poster" :class="'poster-' + posterId">
|
||
<img id="posterSrc" src="" alt="" srcset="">
|
||
</div>
|
||
<div class="poster-cls-btn" @click="hide($event)"></div>
|
||
</div>
|
||
<div class="save-tips">*长按保存海报</div>
|
||
<div class="btn-box">
|
||
<div class="go-draw" @click="goDraw($event)"></div>
|
||
<div class="go-share" @click="goShare($event)"></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
<!-- 分享提示 -->
|
||
<div class="sharePop" @click="hideShare">
|
||
<div class="tips-pic"></div>
|
||
<div class="tips-text">点击右上角分享给你的好友!</div>
|
||
</div>
|
||
</template>
|
||
|
||
|
||
<style lang="scss" scoped>
|
||
.posterPop {
|
||
@include pos(100%, 1624px, 0px, 0px);
|
||
overflow: hidden;
|
||
background: linear-gradient(135deg, #d6d1ca, #e5dccf);
|
||
visibility: hidden;
|
||
|
||
.poster-bg {
|
||
@include pos(750px, 1624px, 0px, 0px);
|
||
// transform: translateY(-50%);
|
||
@include bg_pos("index/bg.jpg");
|
||
}
|
||
|
||
.poster-container {
|
||
@include pos(750px, 1624px, 0px, 0px);
|
||
// transform: translateY(-50%);
|
||
@include flexCen();
|
||
background-color: rgba($color: #000000, $alpha: 0.3);
|
||
|
||
.cls-btn-box {
|
||
width: 617px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
|
||
// .cls-btn {
|
||
// @include box(49px, 49px);
|
||
// @include bg_pos("question-list/cls-btn.png");
|
||
// margin-right: -20px;
|
||
// }
|
||
}
|
||
|
||
.save-tips {
|
||
font-size: 20px;
|
||
line-height: 20px;
|
||
margin-top: 20px;
|
||
color: #9e4b00;
|
||
letter-spacing: 2px;
|
||
}
|
||
|
||
.poster-box {
|
||
@include box(713px, 995px);
|
||
margin-top: 20px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
|
||
.poster-cls-btn{
|
||
@include pos(53px, 53px,660px,10px);
|
||
@include bg_pos("result/cls-btn.png");
|
||
}
|
||
|
||
.poster {
|
||
@include box(100%, 100%);
|
||
overflow: hidden;
|
||
|
||
#posterSrc {
|
||
@include box(100%, 100%);
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
.poster-1 {
|
||
@include bg_pos("result/card-1.png");
|
||
|
||
}
|
||
|
||
.poster-2 {
|
||
@include bg_pos("result/card-2.png");
|
||
}
|
||
|
||
.poster-3 {
|
||
@include bg_pos("result/card-3.png");
|
||
}
|
||
|
||
.poster-4 {
|
||
@include bg_pos("result/card-4.png");
|
||
}
|
||
|
||
.poster-5 {
|
||
@include bg_pos("result/card-5.png");
|
||
}
|
||
|
||
}
|
||
|
||
.poster-box-1{
|
||
@include box(713px, 995px);
|
||
}
|
||
.poster-box-2{
|
||
@include box(711px, 1010px);
|
||
}
|
||
.poster-box-3{
|
||
@include box(713px, 995px);
|
||
}
|
||
.poster-box-4{
|
||
@include box(713px, 995px);
|
||
}
|
||
.poster-box-5{
|
||
@include box(713px, 995px);
|
||
}
|
||
|
||
.btn-box {
|
||
@include box(550px, 104px);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-top: 20px;
|
||
|
||
.go-draw {
|
||
@include box(257px, 104px);
|
||
@include bg_pos("result/go-draw-btn.png");
|
||
}
|
||
|
||
.go-share {
|
||
@include box(274px, 95px);
|
||
@include bg_pos("result/go-share-btn.png");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
.sharePop {
|
||
@include fixed();
|
||
background-color: rgba($color: #000000, $alpha: 0.54);
|
||
visibility: hidden;
|
||
|
||
.tips-pic {
|
||
@include pos(100px, 100px, 600px, 180px);
|
||
@include bg_pos("result/share-tips.svg");
|
||
stroke: #ffffff;
|
||
}
|
||
|
||
.tips-text {
|
||
font-size: 25px;
|
||
@include pos(750px, 100px, 0px, 300px);
|
||
color: #ffffff;
|
||
text-align: right;
|
||
}
|
||
}
|
||
</style> |