437 lines
12 KiB
Vue
437 lines
12 KiB
Vue
<script setup name="Question">
|
||
import gsap from "gsap";
|
||
import { Toast } from "vant";
|
||
import { data } from "@/data";
|
||
import { debounceTap, FYShuffle, mostValue, judgeBigScreen } from "@/plugins";
|
||
import { useMainStore } from "@/store";
|
||
import { subAnswer } from "@/api";
|
||
|
||
// 页面配置初始化
|
||
const emit = defineEmits(["QuestionPage"]);
|
||
const userStore = useMainStore();
|
||
|
||
// 当前题目
|
||
const currentId = ref(0); //当前id 0~11
|
||
const questionList = ref(FYShuffle(data)); //随机打乱题库
|
||
const answerList = ref([]); // 答案库统计
|
||
const activeId = ref(""); // 当前题目所选答案选项
|
||
const showResultBtn = ref(false);
|
||
// 答题事件
|
||
const answerFn = (item, event) => {
|
||
let e = event.target.parentElement.parentElement;
|
||
activeId.value = item.aid;
|
||
debounceTap(e, () => {
|
||
if (currentId.value != 0 && currentId.value != 11) {
|
||
gsap.to(".prev-btn", { duration: 0.5, x: "-=20px", autoAlpha: 0 });
|
||
}
|
||
|
||
if (currentId.value != 11) {
|
||
questionOut.timeScale(2);
|
||
questionOut.restart();
|
||
questionOut.eventCallback("onComplete", () => {
|
||
let cid = questionList.value[currentId.value].id;
|
||
let has = answerList.value.findIndex((obj) => obj.qid === cid);
|
||
if (has == -1) {
|
||
answerList.value.push({
|
||
qid: cid,
|
||
answer: item.secore,
|
||
text: item.text,
|
||
});
|
||
} else {
|
||
answerList.value[has].answer = item.secore;
|
||
answerList.value[has].text = item.text;
|
||
}
|
||
|
||
// 更新下一题信息
|
||
if (currentId.value >= 11) {
|
||
console.log("jieshu");
|
||
Toast("答题结束");
|
||
gsap.set(".answer", { pointerEvents: "none" });
|
||
return;
|
||
} else {
|
||
activeId.value = "";
|
||
currentId.value++;
|
||
}
|
||
questionEntry.timeScale(2);
|
||
questionEntry.restart();
|
||
});
|
||
} else {
|
||
let cid = questionList.value[currentId.value].id;
|
||
let has = answerList.value.findIndex((obj) => obj.qid === cid);
|
||
if (has == -1) {
|
||
answerList.value.push({
|
||
qid: cid,
|
||
answer: item.secore,
|
||
text: item.text,
|
||
});
|
||
} else {
|
||
answerList.value[has].answer = item.secore;
|
||
answerList.value[has].text = item.text;
|
||
}
|
||
resultBtnAni.play();
|
||
}
|
||
console.log("答案库", answerList.value);
|
||
});
|
||
};
|
||
|
||
const mbtiArr = [[], [], [], []]; //四组数组分别存放 E&I,S&T,T&F,J&P四组结果
|
||
const showResult = (event) => {
|
||
let e = event.target;
|
||
gsap.set(".answer-box", { pointerEvents: "none" });
|
||
debounceTap(e, async () => {
|
||
console.log("答题结果:", answerList.value);
|
||
answerList.value.forEach((element) => {
|
||
if (element.answer == "E" || element.answer == "I")
|
||
mbtiArr[0].push(element.answer);
|
||
if (element.answer == "S" || element.answer == "N")
|
||
mbtiArr[1].push(element.answer);
|
||
if (element.answer == "T" || element.answer == "F")
|
||
mbtiArr[2].push(element.answer);
|
||
if (element.answer == "J" || element.answer == "P")
|
||
mbtiArr[3].push(element.answer);
|
||
});
|
||
// console.log('mbtiArr', mbtiArr.value);
|
||
let mbti =
|
||
mostValue(mbtiArr[0]).value +
|
||
mostValue(mbtiArr[1]).value +
|
||
mostValue(mbtiArr[2]).value +
|
||
mostValue(mbtiArr[3]).value;
|
||
console.log("MBTI:", mbti);
|
||
userStore.updateMBTI(mbti);
|
||
|
||
if (import.meta.env.VITE_MODE != "dev") {
|
||
// 提交完成记录
|
||
subAnswer({}, userStore.token).then((res) => {
|
||
console.log("key:", res);
|
||
if (res.code == 0) {
|
||
}
|
||
});
|
||
}
|
||
|
||
// Toast("你的MBTI测试结果:" + mbti);
|
||
resultBtnAni.reverse();
|
||
gsap.to(".prev-btn", { duration: 0.5, x: "-=20px", autoAlpha: 0 });
|
||
questionOut.timeScale(2);
|
||
questionOut.restart();
|
||
questionOut.eventCallback("onComplete", () => {
|
||
gsap.to(".QuestionPage", {
|
||
duration: 0.5,
|
||
autoAlpha: 0,
|
||
onComplete: () => {
|
||
emit("QuestionPage", { action: "showResult" });
|
||
},
|
||
});
|
||
});
|
||
});
|
||
};
|
||
|
||
// 上一页函数
|
||
const prevePage = (event) => {
|
||
let e = event.target;
|
||
debounceTap(e, () => {
|
||
if (currentId.value == 1) {
|
||
gsap.to(".prev-btn", { duration: 0.5, x: "-=20px", autoAlpha: 0 });
|
||
}
|
||
if (currentId.value >= 11) {
|
||
resultBtnAni.reverse();
|
||
gsap.set(".answer", { pointerEvents: "initial" });
|
||
}
|
||
activeId.value = "";
|
||
currentId.value--;
|
||
});
|
||
};
|
||
|
||
// 题目过渡动画
|
||
const questionEntry = gsap.timeline({
|
||
paused: true,
|
||
onStart: () => {
|
||
gsap.set(".answer-box", { pointerEvents: "none" });
|
||
},
|
||
onComplete: () => {
|
||
gsap.set(".answer-box", { pointerEvents: "none" });
|
||
},
|
||
});
|
||
const questionOut = gsap.timeline({
|
||
paused: true,
|
||
onStart: () => {
|
||
gsap.set(".answer-box", { pointerEvents: "none" });
|
||
},
|
||
onComplete: () => {},
|
||
});
|
||
|
||
// 查看结果事件及动画
|
||
const resultBtnAni = gsap.timeline({ paused: true });
|
||
onMounted(() => {
|
||
// 适配
|
||
if (!judgeBigScreen()) {
|
||
gsap.set(".answer-box", { scale: 0.9, marginTop: "-20px" });
|
||
}
|
||
|
||
resultBtnAni.from(".showResult-btn", { y: 200, autoAlpha: 0 });
|
||
questionEntry
|
||
.from(".question", { y: 100, autoAlpha: 0 })
|
||
.from(".answer-0", {
|
||
y: 400,
|
||
scale: 0.3,
|
||
autoAlpha: 0,
|
||
duration: 2,
|
||
ease: "slow(0.7,0.7,false)",
|
||
})
|
||
.from(
|
||
".answer-1",
|
||
{
|
||
y: 400,
|
||
scale: 0.3,
|
||
autoAlpha: 0,
|
||
duration: 2,
|
||
ease: "slow(0.7,0.7,false)",
|
||
onStart: () => {
|
||
gsap.to(".question-bg", {
|
||
backgroundPosition: "0px 0px",
|
||
duration: 1,
|
||
ease: "slow(0.7,0.7,false)",
|
||
});
|
||
},
|
||
onComplete: () => {
|
||
gsap.set(".answer-box", { pointerEvents: "initial" });
|
||
if (currentId.value != 0) {
|
||
gsap.to(".prev-btn", { duration: 0.5, x: "+=20px", autoAlpha: 1 });
|
||
}
|
||
},
|
||
},
|
||
0.5
|
||
)
|
||
.to(".answer-0", { duration: 1, y: "-=10px", repeat: -1, yoyo: true })
|
||
.to(".answer-1", { duration: 1, y: "+=10px", repeat: -1, yoyo: true });
|
||
|
||
questionEntry.play();
|
||
questionOut
|
||
.to(".question", { y: -50, autoAlpha: 0, duration: 0.3 })
|
||
.to(".answer-0", { scale: 0.3, duration: 1 })
|
||
.to(".answer-1", { scale: 0.3, duration: 1 }, 0.5)
|
||
.to(".answer-0", {
|
||
y: -600,
|
||
scale: 0.5,
|
||
autoAlpha: 0,
|
||
duration: 1.5,
|
||
ease: "slow(0.7,0.7,false)",
|
||
onStart: () => {
|
||
gsap.to(".question-bg", {
|
||
backgroundPosition: "0px 835px",
|
||
duration: 0.75,
|
||
ease: "slow(0.7,0.7,false)",
|
||
});
|
||
},
|
||
})
|
||
.to(
|
||
".answer-1",
|
||
{
|
||
y: -600,
|
||
scale: 0.5,
|
||
autoAlpha: 0,
|
||
duration: 1.5,
|
||
ease: "slow(0.7,0.7,false)",
|
||
},
|
||
1.5
|
||
);
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<div class="QuestionPage" @touchmove.prevent>
|
||
<div class="question-bg"></div>
|
||
<div class="question-container">
|
||
<div class="question-content">
|
||
<div class="question">
|
||
<div class="question-order">{{ currentId + 1 }}</div>
|
||
<div class="question-text">
|
||
<div class="text">{{ questionList[currentId].question }}</div>
|
||
</div>
|
||
</div>
|
||
<div class="answer-box">
|
||
<div
|
||
class="answer"
|
||
v-for="(item, index) in questionList[currentId].answer"
|
||
:class="'answer-' + index"
|
||
:key="index"
|
||
>
|
||
<div
|
||
class="answer-bg"
|
||
:class="activeId == item.aid ? 'active' : ''"
|
||
></div>
|
||
<div class="answer-text">
|
||
<div class="content-before"></div>
|
||
<div class="content-after"></div>
|
||
<div class="text" @click="answerFn(item, $event)">
|
||
{{ item.aid }}<br />{{ item.text }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 查看结果 -->
|
||
<div class="showResult-btn" @click="showResult"></div>
|
||
<!-- 上一页 -->
|
||
<div class="prev-btn" @click="prevePage($event)"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style lang='scss' scope>
|
||
.QuestionPage {
|
||
@include pos(100%, 100%, 0px, 0px);
|
||
overflow: hidden;
|
||
|
||
.question-bg {
|
||
@include pos(750px, 4500px, 0px, 50%);
|
||
transform: translateY(-50%);
|
||
background: linear-gradient(135deg, #f6d365, #fda085);
|
||
}
|
||
|
||
.question-container {
|
||
@include pos(750px, 100%, 0px, 50%);
|
||
transform: translateY(-50%);
|
||
@include flexCen();
|
||
|
||
.question-content {
|
||
@include box(100%, 100%);
|
||
@include flexCen();
|
||
|
||
.question {
|
||
position: relative;
|
||
@include box(713px, 428px);
|
||
@include bg_pos("qa/question.png");
|
||
font-family: "alimama";
|
||
color: #c6672c;
|
||
|
||
.question-order {
|
||
@include pos(544px, 75px, 87px, 112px);
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 66px;
|
||
font-weight: 700;
|
||
line-height: 80px;
|
||
}
|
||
|
||
.question-text {
|
||
@include pos(544px, 170px, 87px, 192px);
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 40px;
|
||
font-weight: 700;
|
||
// line-height: 50px;
|
||
|
||
.text {
|
||
width: 90%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-content: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
.answer-box {
|
||
// display: flex;
|
||
// flex-direction: column;
|
||
@include box(750px, 886px);
|
||
// margin-top: 10px;
|
||
position: relative;
|
||
|
||
.answer {
|
||
@include box(481px, 471px);
|
||
position: absolute;
|
||
// font-family: "alimama";
|
||
color: #c6672c;
|
||
|
||
.answer-bg {
|
||
@include pos(481px, 471px, 0px, 0px);
|
||
@include bg_pos("qa/answer-box-1.png");
|
||
pointer-events: none;
|
||
}
|
||
|
||
.active {
|
||
@include bg_pos("qa/answer-box-2.png");
|
||
|
||
// color: rgb(255, 255, 255);
|
||
}
|
||
|
||
.answer-text {
|
||
// @include pos(367px, 357px, 0px, 0px);
|
||
position: relative;
|
||
left: 58px;
|
||
top: 58px;
|
||
@include box(367px, 357px);
|
||
padding: 10px;
|
||
border-radius: 50%;
|
||
|
||
font-size: 35px;
|
||
font-weight: 700;
|
||
border-radius: 50%;
|
||
// .content-before {
|
||
// pointer-events: none;
|
||
// float: left;
|
||
// width: 50%;
|
||
// height: 100%;
|
||
// shape-outside: radial-gradient(
|
||
// farthest-side ellipse at right,
|
||
// transparent 98%,
|
||
// red
|
||
// );
|
||
// }
|
||
// .content-after {
|
||
// pointer-events: none;
|
||
|
||
// float: right;
|
||
// width: 50%;
|
||
// height: 100%;
|
||
// shape-outside: radial-gradient(
|
||
// farthest-side ellipse at left,
|
||
// transparent 98%,
|
||
// red
|
||
// );
|
||
// }
|
||
.text {
|
||
@include box(367px, 357px);
|
||
padding: 0px 20px;
|
||
box-sizing: border-box;
|
||
position: absolute;
|
||
text-align: center;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding-bottom: 20px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.answer:nth-child(1) {
|
||
top: 0px;
|
||
left: 6px;
|
||
}
|
||
|
||
.answer:nth-child(2) {
|
||
top: 414px;
|
||
left: 258px;
|
||
}
|
||
}
|
||
|
||
.prev-btn {
|
||
@include pos(148px, 61px, 50px, 600px);
|
||
@include bg_pos("qa/prev-btn.png");
|
||
visibility: hidden;
|
||
}
|
||
|
||
.showResult-btn {
|
||
@include box(478px, 246px);
|
||
position: fixed;
|
||
left: 149px;
|
||
bottom: 0px;
|
||
@include bg_pos("qa/showResult-btn.png");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |