palc-newyear2024/src/components/Question.vue

375 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup name="Question">
import { Button, Toast } from "vant";
import gsap from "gsap";
import data from "@/data";
import { debounceTap, FYShuffle, mostValue } from "@/plugins";
import { onMounted } from "vue";
// 页面配置初始化
const emit = defineEmits(["QuestionPage"]);
// 当前题目
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", () => {
console.log("题目:", currentId.value);
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 {
resultBtnAni.play();
}
console.log("答案库", answerList.value);
});
};
const mbtiArr = ref([[], [], [], []]); //四组数组分别存放 E&IS&TT&FJ&P四组结果
const showResult = (event) => {
let e = event.target;
debounceTap(e, () => {
// console.log('答题结果:', answerList.value);
answerList.value.forEach((element) => {
if (element.answer == "E" || element.answer == "I")
mbtiArr.value[0].push(element.answer);
if (element.answer == "S" || element.answer == "N")
mbtiArr.value[1].push(element.answer);
if (element.answer == "T" || element.answer == "F")
mbtiArr.value[2].push(element.answer);
if (element.answer == "J" || element.answer == "P")
mbtiArr.value[3].push(element.answer);
});
// console.log('mbtiArr', mbtiArr.value);
let mbti =
mostValue(mbtiArr.value[0]).value +
mostValue(mbtiArr.value[1]).value +
mostValue(mbtiArr.value[2]).value +
mostValue(mbtiArr.value[3]).value;
console.log("MBTI:", mbti);
Toast("你的MBTI测试结果:" + mbti);
});
};
// 上一页函数
const prevePage = (event) => {
let e = event.target;
debounceTap(e, () => {
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--;
// questionEntry.reverse(0.3);
// questionEntry.restart(true);
// setTimeout(()=>{})
});
};
// 题目过渡动画
const questionEntry = gsap.timeline({
paused: true,
onStart: () => {
gsap.set(".answer-box", { pointerEvents: "none" });
},
onComplete: () => {
if (currentId.value != 0) {
gsap.to(".prev-btn", { duration: 0.5, x: "+=20px", autoAlpha: 1 });
}
gsap.set(".answer-box", { pointerEvents: "initial" });
},
});
const questionOut = gsap.timeline({
paused: true,
onStart: () => {
gsap.set(".answer-box", { pointerEvents: "none" });
},
onComplete: () => {
gsap.set(".answer-box", { pointerEvents: "initial" });
},
});
// 查看结果事件及动画
const resultBtnAni = gsap.timeline({ paused: true });
onMounted(() => {
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)",
},
0.5
);
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)",
})
.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);
background-color: rgb(68, 208, 112);
overflow: hidden;
.question-bg {
@include pos(750px, 100%, 0px, 50%);
transform: translateY(-50%);
@include bg_pos("qa/bg.jpg");
}
.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, 150px, 87px, 192px);
box-sizing: border-box;
// padding-bottom: 20px;
display: flex;
justify-content: center;
align-items: center;
font-size: 40px;
font-weight: 700;
line-height: 50px;
.text {
width: 80%;
// height: 100%;
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>