This commit is contained in:
Andy Leong
2024-01-20 02:35:49 +08:00
parent fc0d5fce8c
commit 28dc4ec60d
11 changed files with 709 additions and 479 deletions

View File

@@ -3,404 +3,468 @@ import { gsap } from "gsap";
import { debounceTap } from "@/plugins";
import { useMainStore } from "@/store";
import { mbtiList } from "@/data";
import { posterCreate } from '@/plugins'
import { posterCreate } from "@/plugins";
import { Toast } from "vant";
import { onBeforeMount } from "vue";
import { computed } from "vue";
import QRCode from "qrcode";
// 页面配置初始化
const emit = defineEmits(["ResultPage"]);
const userStore = useMainStore();
let bgId = ref(1); //海报背景id14
let bgId = ref(1); //海报背景id14
const bgPic = computed(() => {
return new URL(
`../assets/images/result/bg-${bgId.value}.jpg`,
import.meta.url
).href;
return new URL(
`../assets/images/result/bg-${bgId.value}.jpg`,
import.meta.url
).href;
});
// 主题配色
const theme = reactive(['#d3473a', '#fb7700', '#4172d8', '#eb5c37'])
const theme = reactive(["#d3473a", "#fb7700", "#4172d8", "#eb5c37"]);
const mbti = ref(userStore.MBTI);
const mbtiObj = ref(mbtiList.find(item => item.type == mbti.value))
console.log("mbti", mbti.value);
onBeforeMount(() => {
// mbtiObj.value = mbtiList.find(item => item.type == mbti.value)
console.log('mbtiObj.value', mbtiObj.value);
})
const mbtiObj = ref(mbtiList.find((item) => item.type == mbti.value));
const changBg = (event, number) => {
let e = event.target;
if (number == bgId.value) return;
bgId.value = number;
debounceTap(
e,
() => {
// console.log("bgId", bgId.value);
},
0.3
);
let e = event.target;
if (number == bgId.value) return;
bgId.value = number;
debounceTap(
e,
() => {
// console.log("bgId", bgId.value);
},
0.3
);
};
// With async/await
const eqcodePic = ref();
onMounted(() => {
let eqCodeUrl = import.meta.env.VITE_URL;
console.log("url:", eqCodeUrl);
QRCode.toDataURL(eqCodeUrl)
.then((url) => {
eqcodePic.value = url;
console.log("eq", eqcodePic.value);
})
.catch((err) => {
console.error(err);
});
});
const createPoster = (event) => {
let e = event.target
debounceTap(e, () => {
// 海报生成
posterCreate(
{ width: 750, height: 1500 }, //海报尺寸
// 海报素材,按顺序依次渲染
[
// 背景
{
src: new URL('../assets/images/result/poster-bg-' + bgId.value + '.jpg', import.meta.url).href,
pos: { w: 750, h: 1500, x: 0, y: 0 }
},
// 产品
{
src: mbtiObj.value.productPic,
pos: { w: 469, h: 102, x: 137, y: 911 }
},
],
// 字体素材
[
// mbti title及职业
{
content: mbtiObj.value.type + mbtiObj.value.job,
style: {
font: 'normal 80px HYYakuHei',
pos: { x: 70, y: 330 }
}
},
// mbti 描述
{
content: mbtiObj.value.des[0],
style: {
font: 'normal 30px fzzy',
color: '#af6f49',
pos: { x: 70, y: 470 }
}
},
{
content: mbtiObj.value.des[1],
style: {
font: 'normal 30px fzzy',
color: '#af6f49',
pos: { x: 70, y: 520 }
}
},
// 新年寄语
{
content: mbtiObj.value.blessings[0],
style: {
font: 'normal 50px fzcy',
pos: { x: 70, y: 650 }
}
},
{
content: mbtiObj.value.blessings[1],
style: {
font: 'normal 50px fzcy',
pos: { x: 70, y: 725 }
}
},
// 产品
{
content: mbtiObj.value.product,
style: {
font: 'normal 50px fzcy',
pos: { x: 70, y: 876 }
}
}
],
// 主题配色
theme[bgId.value - 1]
)
}, 0.4)
}
let e = event.target;
debounceTap(
e,
() => {
// 海报生成
posterCreate(
{ width: 750, height: 1500 }, //海报尺寸
// 海报素材,按顺序依次渲染
[
// 背景
{
name: "bg",
src: new URL(
"../assets/images/result/poster-bg-" + bgId.value + ".jpg",
import.meta.url
).href,
pos: { w: 750, h: 1500, x: 0, y: 0 },
},
// 产品
{
name: "product",
src: mbtiObj.value.productPic,
pos: { w: 469, h: 102, x: 137, y: 911 },
},
// 二维码
{
name: "eqcode",
src: eqcodePic.value,
pos: { w: 140, h: 140, x: 66, y: 1070 },
},
],
// 字体素材
[
// mbti title及职业
{
content: mbtiObj.value.type + mbtiObj.value.job,
style: {
font: "normal 80px HYYakuHei",
pos: { x: 70, y: 330 },
},
},
// mbti 描述
{
content: mbtiObj.value.des[0],
style: {
font: "normal 30px fzzy",
color: "#af6f49",
pos: { x: 70, y: 470 },
},
},
{
content: mbtiObj.value.des[1],
style: {
font: "normal 30px fzzy",
color: "#af6f49",
pos: { x: 70, y: 520 },
},
},
// 新年寄语
{
content: mbtiObj.value.blessings[0],
style: {
font: "normal 50px fzcy",
pos: { x: 70, y: 650 },
},
},
{
content: mbtiObj.value.blessings[1],
style: {
font: "normal 50px fzcy",
pos: { x: 70, y: 725 },
},
},
// 产品
{
content: mbtiObj.value.product,
style: {
font: "normal 50px fzcy",
pos: { x: 70, y: 876 },
},
},
],
// 主题配色
theme[bgId.value - 1]
);
},
0.4
);
};
const goDraw = (event) => {
let e = event.target
debounceTap(e, () => {
if (userStore.hasDraw) {
emit('ResultPage', { action: 'showDraw' })
} else {
Toast('暂无抽奖机会')
}
})
}
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 });
});
};
const goShare = (event) => {
let e = event.target
debounceTap(e, () => {
})
}
const hidePop = (event) => {
let e = event.target
debounceTap(e, () => {
gsap.to('.posterPop', { duration: 0.5, autoAlpha: 0 })
})
}
let e = event.target;
debounceTap(e, () => {
gsap.to(".sharePop", { duration: 0.5, autoAlpha: 1 });
});
};
const hideShare = () => {
gsap.to(".sharePop", { duration: 0.5, autoAlpha: 0 });
};
</script>
<template>
<div class="ResultPage" @touchmove.prevent>
<div class="result-bg">
<img :src="bgPic" alt="" srcset="" />
</div>
<div class="result-container">
<div :class="'page-theme-' + bgId">
<div class="mbti-title"><span>{{ mbtiObj.type }} {{ mbtiObj.job }}</span></div>
<div class="mbti-des-box">
<div class="des" v-for="item in mbtiObj.des">{{ item }}</div>
</div>
<div class="mbti-blessings-box">
<div class="blessings" v-for="item in mbtiObj.blessings">{{ item }}</div>
</div>
<div class="mbti-product">
<div class="product">{{ mbtiObj.product }}</div>
<div class="produc-img">
<img :src="mbtiObj.productPic" alt="" srcset="">
</div>
</div>
</div>
<div class="theme-tab">
<div class="theme-select-tips"></div>
<div class="theme-list">
<div :class="{ active: bgId == item }" v-for="item in 4" @click="changBg($event, item)">
<div class="theme-li" :class="'theme-li-' + item"></div>
<div class="selected" v-show="bgId == item"></div>
</div>
</div>
<div class="create-btn" @click="createPoster($event)"></div>
</div>
</div>
<div class="ResultPage" @touchmove.prevent>
<div class="result-bg">
<img :src="bgPic" alt="" srcset="" />
</div>
<!-- 海报弹窗 -->
<div class="posterPop" @touchmove.prevent>
<div class="cls-btn" @click="hidePop($event)"></div>
<div class="poster-box">
<img id="poster">
<div class="result-container">
<div :class="'page-theme-' + bgId">
<div class="mbti-title">
<span>{{ mbtiObj.type }} {{ mbtiObj.job }}</span>
</div>
<div class="btn-box">
<div class="go-draw" @click="goDraw($event)"></div>
<div class="go-share" @click="goShare($event)"></div>
<div class="mbti-des-box">
<div class="des" v-for="item in mbtiObj.des">{{ item }}</div>
</div>
<div class="mbti-blessings-box">
<div class="blessings" v-for="item in mbtiObj.blessings">
{{ item }}
</div>
</div>
<div class="mbti-product">
<div class="product">{{ mbtiObj.product }}</div>
<div class="produc-img">
<img :src="mbtiObj.productPic" alt="" srcset="" />
</div>
</div>
</div>
<div class="theme-tab">
<div class="theme-select-tips"></div>
<div class="theme-list">
<div
class="theme-li-border"
:class="{ active: bgId == item }"
v-for="item in 4"
@click="changBg($event, item)"
>
<div class="theme-li" :class="'theme-li-' + item"></div>
<div class="selected" v-show="bgId == item"></div>
</div>
</div>
<div class="create-btn" @click="createPoster($event)"></div>
</div>
</div>
</div>
<!-- 海报弹窗 -->
<div class="posterPop" @touchmove.prevent>
<div class="cls-btn-box">
<div class="cls-btn" @click="hidePop($event)"></div>
</div>
<div class="poster-box">
<img id="poster" />
</div>
<div class="btn-box">
<div class="go-draw" @click="goDraw($event)"></div>
<div class="go-share" @click="goShare($event)"></div>
</div>
</div>
<!-- 分享提示 -->
<div class="sharePop" @click="hideShare">
<div class="tips-pic"></div>
<div class="tips-text">点击右上角分享给你的好友</div>
</div>
</template>
<style lang="scss" scoped>
.ResultPage {
@include fixed();
background-color: azure;
@include fixed();
background-color: azure;
.result-bg {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
pointer-events: none;
.result-bg {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
pointer-events: none;
img {
@include box(100%, 100%);
}
}
.result-container {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
.page-theme-1 {
color: #d3473a;
animation: color 1s;
}
.page-theme-2 {
color: #fb7700;
animation: color 1s;
}
.page-theme-3 {
color: #4172d8;
animation: color 1s;
}
.page-theme-4 {
color: #eb5c37;
animation: color 1s;
}
.mbti-title {
@include pos(480px, 120px, 90px, 418px);
font-size: 80px;
font-family: "HYYaKuHei";
text-align: center;
text-shadow: 3.109px 2.517px 4px rgba(215, 70, 56, 0.47);
text-stroke: 1px #ffffff;
-webkit-text-stroke: 1px #ffffff;
// -webkit-transform: matrix(2.63538838101382, -0.15627262233171, 0.15650043026188, 2.63155221026798, 0, 0);
font-weight: bolder;
transform: rotate(-4deg);
display: flex;
span {
}
}
.mbti-des-box {
@include pos(517px, 90px, 110px, 547px);
display: flex;
flex-direction: column;
justify-content: space-around;
font-family: "fzzy";
.des {
color: #af6f49;
font-size: 30px;
transform: rotate(-4deg);
}
}
.mbti-blessings-box {
@include pos(500px, 140px, 130px, 720px);
display: flex;
flex-direction: column;
justify-content: space-between;
font-family: "fzcy";
.blessings {
font-size: 50px;
transform: rotate(-4deg);
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.004);
}
}
.mbti-product {
@include pos(475px, 140px, 134px, 948px);
font-family: "fzcy";
.product {
font-size: 45px;
transform: rotate(-3deg);
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.004);
}
.produc-img {
@include box(469px, 102px);
margin-left: 10px;
img {
@include box(100%, 100%);
width: 100%;
}
}
}
.result-container {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
.theme-tab {
@include pos(487px, 240px, 161px, 1108px);
transform: rotate(-3deg);
.page-theme-1 {
color: #d3473a;
animation: color 1s;
.theme-select-tips {
@include pos(250px, 21px, 118.5px, 0px);
@include bg_pos("result/select-tips.png");
}
.theme-list {
@include pos(483px, 116px, 2.5px, 36px);
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
.theme-li-border {
// @include box(97px, 98px);
.theme-li {
@include box(97px, 98px);
}
}
.page-theme-2 {
color: #fb7700;
animation: color 1s;
.active {
@include box(115px, 116px);
position: relative;
border-style: solid;
border-width: 8px;
border-color: rgb(255, 70, 76);
border-radius: 20px;
}
.page-theme-3 {
color: #4172d8;
animation: color 1s;
.theme-li-1 {
@include bg_pos("result/theme-1.png");
}
.page-theme-4 {
color: #eb5c37;
animation: color 1s;
.theme-li-2 {
@include bg_pos("result/theme-2.png");
}
.mbti-title {
@include pos(480px, 120px, 90px, 418px);
font-size: 80px;
font-family: "HYYaKuHei";
text-align: center;
text-shadow: 3.109px 2.517px 4px rgba(215, 70, 56, 0.47);
text-stroke: 1px #ffffff;
-webkit-text-stroke: 1px #ffffff;
// -webkit-transform: matrix(2.63538838101382, -0.15627262233171, 0.15650043026188, 2.63155221026798, 0, 0);
font-weight: bolder;
transform: rotate(-4deg);
display: flex;
span {}
.theme-li-3 {
@include bg_pos("result/theme-3.png");
}
.mbti-des-box {
@include pos(517px, 90px, 110px, 547px);
display: flex;
flex-direction: column;
justify-content: space-around;
font-family: 'fzzy';
.des {
color: #af6f49;
font-size: 30px;
transform: rotate(-4deg);
}
.theme-li-4 {
@include bg_pos("result/theme-4.png");
}
.mbti-blessings-box {
@include pos(500px, 140px, 130px, 720px);
display: flex;
flex-direction: column;
justify-content: space-between;
font-family: 'fzcy';
.blessings {
font-size: 50px;
transform: rotate(-4deg);
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.004);
}
.selected {
@include bg_pos("result/select-arrow.png");
@include pos(15px, 8px, 45px, 110px);
}
}
.mbti-product {
@include pos(475px, 140px, 134px, 948px);
font-family: 'fzcy';
.product {
font-size: 45px;
transform: rotate(-3deg);
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.004);
}
.produc-img {
@include box(469px, 102px);
margin-left: 10px;
img {
width: 100%;
}
}
}
.theme-tab {
@include pos(487px, 240px, 161px, 1108px);
.theme-select-tips {
@include pos(250px, 21px, 118.5px, 0px);
@include bg_pos("result/select-tips.png");
}
.theme-list {
@include pos(483px, 116px, 2.5px, 36px);
display: flex;
flex-direction: row;
justify-content: space-around;
.active {
border-style: solid;
border-width: 8px;
border-color: rgb(255, 70, 76);
border-radius: 20px;
}
.theme-li {
@include box(97px, 98px);
position: relative;
}
.theme-li-1 {
@include bg_pos("result/theme-1.png");
}
.theme-li-2 {
@include bg_pos("result/theme-2.png");
}
.theme-li-3 {
@include bg_pos("result/theme-3.png");
}
.theme-li-4 {
@include bg_pos("result/theme-4.png");
}
.selected {
@include bg_pos("result/select-arrow.png");
@include pos(15px, 8px, 60px, 120px);
}
}
.create-btn {
@include pos(258px, 69px, 126px, 159px);
@include bg_pos("result/create-btn.png");
}
}
.create-btn {
@include pos(258px, 69px, 126px, 165px);
@include bg_pos("result/create-btn.png");
}
}
}
}
.posterPop {
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.54);
visibility: hidden;
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.54);
visibility: hidden;
.cls-btn-box {
width: 495px;
display: flex;
justify-content: flex-end;
.cls-btn {
@include box(41px, 41px);
@include bg_pos("result/cls-btn.png");
@include box(41px, 41px);
@include bg_pos("result/cls-btn.png");
margin-right: -20px;
}
}
.poster-box {
@include box(495px, 990px);
margin-top: 20px;
overflow: hidden;
border: 2px solid #dbbb90;
border-radius: 20px;
#poster {
@include box(100%, 100%);
}
}
.btn-box {
@include box(489px, 76px);
display: flex;
justify-content: space-between;
margin-top: 20px;
.go-draw {
@include box(226px, 76px);
@include bg_pos("result/go-draw-btn.png");
}
.poster-box {
@include box(495px, 990px);
overflow: hidden;
border: 2px solid #dbbb90;
border-radius: 20px;
#poster {
@include box(100%, 100%);
}
.go-share {
@include box(226px, 76px);
@include bg_pos("result/go-share-btn.png");
}
}
}
.btn-box {
@include box(489px, 76px);
display: flex;
justify-content: space-between;
margin-top: 20px;
.go-draw {
@include box(226px, 76px);
@include bg_pos("result/go-draw-btn.png");
}
.go-share {
@include box(226px, 76px);
@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, 100px);
@include bg_pos("result/share-tips.svg");
stroke: #ffffff;
}
.tips-text {
font-family: "fzcy";
font-size: 25px;
@include pos(750px, 100px, 0px, 220px);
color: #ffffff;
text-align: right;
}
}
</style>