Files
faceFamilySource/src/components/SynthesizedResults.vue
2025-09-23 15:28:34 +08:00

277 lines
6.6 KiB
Vue

<script setup>
import { ref, onMounted, computed } from "vue"
import { useRouter } from 'vue-router'
import Popup from './Popup.vue'
import { globalStore } from "../globalstore.js";
import globalToastEvent, { ToastType } from '../globalToastEvent';
import { Storage, generateQR } from "../libs/utils";
import Haibao from "@/libs/haibao";
import mask from "../assets/images/haibao-mask.webp";
import haibaoCoverBorder from "../assets/images/haibao-cover-sucess.webp";
import bg from "../assets/images/haibao-bg.webp"
import Lottery from '../components/Lottery.vue';
defineProps({
show: true
})
const isPopupVisible = ref(false);
const lotteryShow = ref(false)
const chartsBattle = ()=> {
globalStore.chartsBattle = true;
isPopupVisible.value = true;
}
const router = useRouter();
const navigateToHome = () => {
router.push({
name: 'home'
})
}
const handleLottery = () => {
globalToastEvent.emit(ToastType.SHOW_LOTTERY)
}
// 海报
const haibaoShow = ref(false);
const haibaoUrl = ref('');
const userHaibaoUrl = ref('');
const userhaibaoCover = computed(() => {
return { backgroundImage: `url(${userHaibaoUrl.value})` }
})
const openHaibao = (e) => {
haibaoShow.value = true
handleHaibao()
}
onMounted(openHaibao)
const loadImage = (src)=> {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => resolve(img);
img.onerror = () => reject(new Error(`无法加载图片: ${src}`));
img.src = src;
});
}
const handleHaibao = async () => {
if (haibaoUrl.value) {
return
}
const loading = weui.loading()
const infos = Storage.get("userinfos")
const haibaoCover = new Haibao(951, 1607)
if (!globalStore.result_url) {
router.push({
name: 'home'
});
}
const userPicture = await loadImage(globalStore.result_url)
haibaoCover.add(userPicture, 0, 50, 951, 1698)
haibaoCover.add(mask, 10, 100)
haibaoCover.add(haibaoCoverBorder, 0, 0)
haibaoCover.draw('destination-in').then(() => {
haibaoCover.generate({ mimeType: 'image/png' }).then(async (url) => {
userHaibaoUrl.value = url
const haibaoSave = new Haibao(1080, 2160)
const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${infos.merge_id}`, 200, 200)
haibaoSave.add(bg, 0, 0)
haibaoSave.add(url, 64, 250)
haibaoSave.add(qrcode, 127, 1860)
haibaoSave.draw().then(() => {
haibaoSave.text(infos.nickname + '的全家福', haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#fcf2b3' })
haibaoSave.generate({ mimeType: 'image/png' }).then(url => {
// haibaoUrl.value = url
haibaoUrl.value = globalStore.result_url;
loading.hide()
}).catch(err => {
console.log(err)
weui.alert("海报生成失败,请重新生成")
loading.hide()
})
}).catch(err => {
console.log(err)
weui.alert("海报生成失败,请重新生成")
loading.hide()
})
})
})
}
// let userPictureVal = userPicture;
// const getBackgroundImage = () => {
// if (globalStore.result_url) {
// return userPictureVal = globalStore.result_url;
// } else {
// return userPictureVal;
// }
// };
globalToastEvent.on(ToastType.SHOW_LOTTERY, () => {
lotteryShow.value = true
})
</script>
<template>
<div class="main">
<div class="home-wrapper">
<div class="scene-item item-1">
<img src="../assets/images/go-home-btn.webp" @click="navigateToHome" alt="回到首页">
</div>
<!-- <div class="mask-background image-container" :style="{ backgroundImage: `url(${getBackgroundImage()})` }">
</div>
<img src="../assets/images/mengban-border.webp" class="mengban-border" alt="蒙版"> -->
<div class="fullsection" v-show="haibaoShow">
<div class="haibao" :style="userhaibaoCover">
<img :src="haibaoUrl" alt="">
<!-- <div class="close" @click="haibaoShow = false"></div> -->
</div>
</div>
<div class="scene-item item-2">
<img src="../assets/images/charts-battle.webp" @click="chartsBattle" alt="参与打榜">
</div>
<div class="scene-item item-3" @click="handleLottery">
<img src="../assets/images/instant-win.webp" alt="立即抽奖">
</div>
</div>
</div>
<Popup v-model:show="isPopupVisible" />
<Lottery :show="lotteryShow" @close="lotteryShow = false"></Lottery>
</template>
<style scoped>
.mask-background {
-webkit-mask-image: url("../assets/images/my-photo-mengban.webp");
mask-image: url("../assets/images/my-photo-mengban.webp");
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
.mengban-border {
width: 81vw;
position: absolute;
top: 28vw;
}
.image-container {
width: 80vw;
top: 5.2vw;
margin-bottom: 3vw;
background-image: url('../assets/images/home-bg.webp');
background-size: cover;
background-repeat: no-repeat;
min-height: -webkit-fill-available;
position: absolute;
cursor: pointer;
}
.fullsection {
position: absolute;
top: 40vw;
left: 0;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
.haibao {
width: 70vw;
height: 119.444444vw;
background-image: url("../assets/images/haibao-cover.webp");
background-repeat: no-repeat;
background-size: 100%;
}
.haibao img {
width: 100%;
height: 100%;
display: block;
opacity: 0;
}
.close {
position: absolute;
width: 8.148148vw;
height: 8.148148vw;
right: 5vw;
top: 15vw;
background-image: url("../assets/images/close-btn.webp");
background-repeat: no-repeat;
background-size: 100%;
}
.haibao .close {
left: 50%;
bottom: -5vw;
top: initial;
transform: translate3d(-50%,0,0);
}
.main {
height: 100%;
overflow-y: auto;
}
.home-wrapper {
width: 100vw;
background-image: url('../assets/images/img-result-bg.webp');
background-size: cover;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
min-height: -webkit-fill-available;
}
.scene-item {
position: absolute;
cursor: pointer;
transition: all 0.4s ease;
border-radius: 8px;
overflow: hidden;
border: 3px solid transparent;
animation: float 4s ease-in-out infinite;
}
.scene-item:hover {
transform: scale(1.05);
}
.scene-item img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.item-1 {
width: 16vw;
top: 6.7%;
left: 5%;
animation-delay: 0s;
}
.item-2 {
width: 45vw;
bottom: 3%;
left: 5%;
}
.item-3 {
width: 45vw;
bottom: 3%;
right: 5%;
}
</style>