diff --git a/package.json b/package.json index 5139ba9..8fd1306 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "pinia": "^2.1.7", "qrcode": "^1.5.3", "qs": "^6.11.2", + "swiper": "^11.2.1", "vant": "^3.6.12", "vconsole": "^3.15.1", "vue": "^3.2.41", diff --git a/src/assets/font/DouyinSansBold.ttf b/src/assets/font/DouyinSansBold.ttf index 0082a4b..d84cdd9 100644 Binary files a/src/assets/font/DouyinSansBold.ttf and b/src/assets/font/DouyinSansBold.ttf differ diff --git a/src/assets/images/index/pet-icon.png b/src/assets/images/index/pet-icon.png index 2e22177..24a535b 100644 Binary files a/src/assets/images/index/pet-icon.png and b/src/assets/images/index/pet-icon.png differ diff --git a/src/assets/images/index/windows.png b/src/assets/images/index/windows.png index 0a0c47b..ac5aafe 100644 Binary files a/src/assets/images/index/windows.png and b/src/assets/images/index/windows.png differ diff --git a/src/assets/images/poster/card-1.png b/src/assets/images/poster/card-1.png new file mode 100644 index 0000000..105f97b Binary files /dev/null and b/src/assets/images/poster/card-1.png differ diff --git a/src/assets/images/qa/baozhu.png b/src/assets/images/qa/baozhu.png new file mode 100644 index 0000000..07ef1c8 Binary files /dev/null and b/src/assets/images/qa/baozhu.png differ diff --git a/src/assets/images/qa/create-btn.png b/src/assets/images/qa/create-btn.png index 13e46a6..3c25a9d 100644 Binary files a/src/assets/images/qa/create-btn.png and b/src/assets/images/qa/create-btn.png differ diff --git a/src/assets/images/qa/go-back.png b/src/assets/images/qa/go-back.png new file mode 100644 index 0000000..e552de7 Binary files /dev/null and b/src/assets/images/qa/go-back.png differ diff --git a/src/assets/images/qa/lantern-icon.png b/src/assets/images/qa/lantern-icon.png index f5c13d3..45512f8 100644 Binary files a/src/assets/images/qa/lantern-icon.png and b/src/assets/images/qa/lantern-icon.png differ diff --git a/src/assets/images/qa/question-box.png b/src/assets/images/qa/question-box.png index 6a28b45..e3b0954 100644 Binary files a/src/assets/images/qa/question-box.png and b/src/assets/images/qa/question-box.png differ diff --git a/src/assets/images/question-list/bg.jpg b/src/assets/images/question-list/bg.jpg new file mode 100644 index 0000000..6f45ae2 Binary files /dev/null and b/src/assets/images/question-list/bg.jpg differ diff --git a/src/assets/images/question-list/bottom-bg.png b/src/assets/images/question-list/bottom-bg.png new file mode 100644 index 0000000..6c1f33b Binary files /dev/null and b/src/assets/images/question-list/bottom-bg.png differ diff --git a/src/assets/images/question-list/bottom-icon-1.png b/src/assets/images/question-list/bottom-icon-1.png new file mode 100644 index 0000000..e82a5b3 Binary files /dev/null and b/src/assets/images/question-list/bottom-icon-1.png differ diff --git a/src/assets/images/question-list/bottom-icon-2.png b/src/assets/images/question-list/bottom-icon-2.png new file mode 100644 index 0000000..114bd1d Binary files /dev/null and b/src/assets/images/question-list/bottom-icon-2.png differ diff --git a/src/assets/images/question-list/box.png b/src/assets/images/question-list/box.png new file mode 100644 index 0000000..05a1492 Binary files /dev/null and b/src/assets/images/question-list/box.png differ diff --git a/src/assets/images/question-list/cls-btn.png b/src/assets/images/question-list/cls-btn.png new file mode 100644 index 0000000..c35458e Binary files /dev/null and b/src/assets/images/question-list/cls-btn.png differ diff --git a/src/assets/images/question-list/firework-icon.png b/src/assets/images/question-list/firework-icon.png new file mode 100644 index 0000000..5a053a7 Binary files /dev/null and b/src/assets/images/question-list/firework-icon.png differ diff --git a/src/assets/images/question-list/gift-1.png b/src/assets/images/question-list/gift-1.png new file mode 100644 index 0000000..9468812 Binary files /dev/null and b/src/assets/images/question-list/gift-1.png differ diff --git a/src/assets/images/question-list/gift-2.png b/src/assets/images/question-list/gift-2.png new file mode 100644 index 0000000..91c61d9 Binary files /dev/null and b/src/assets/images/question-list/gift-2.png differ diff --git a/src/assets/images/question-list/icon-1.png b/src/assets/images/question-list/icon-1.png new file mode 100644 index 0000000..a5d6aa3 Binary files /dev/null and b/src/assets/images/question-list/icon-1.png differ diff --git a/src/assets/images/question-list/icon-2.png b/src/assets/images/question-list/icon-2.png new file mode 100644 index 0000000..292247f Binary files /dev/null and b/src/assets/images/question-list/icon-2.png differ diff --git a/src/assets/images/question-list/icon-3.png b/src/assets/images/question-list/icon-3.png new file mode 100644 index 0000000..d4382fb Binary files /dev/null and b/src/assets/images/question-list/icon-3.png differ diff --git a/src/assets/images/question-list/larnten-1.png b/src/assets/images/question-list/larnten-1.png new file mode 100644 index 0000000..59f1eba Binary files /dev/null and b/src/assets/images/question-list/larnten-1.png differ diff --git a/src/assets/images/question-list/larnten-10.png b/src/assets/images/question-list/larnten-10.png new file mode 100644 index 0000000..23b21f3 Binary files /dev/null and b/src/assets/images/question-list/larnten-10.png differ diff --git a/src/assets/images/question-list/larnten-11.png b/src/assets/images/question-list/larnten-11.png new file mode 100644 index 0000000..d81904f Binary files /dev/null and b/src/assets/images/question-list/larnten-11.png differ diff --git a/src/assets/images/question-list/larnten-2.png b/src/assets/images/question-list/larnten-2.png new file mode 100644 index 0000000..c7122d5 Binary files /dev/null and b/src/assets/images/question-list/larnten-2.png differ diff --git a/src/assets/images/question-list/larnten-3.png b/src/assets/images/question-list/larnten-3.png new file mode 100644 index 0000000..0fc930f Binary files /dev/null and b/src/assets/images/question-list/larnten-3.png differ diff --git a/src/assets/images/question-list/larnten-4.png b/src/assets/images/question-list/larnten-4.png new file mode 100644 index 0000000..683424e Binary files /dev/null and b/src/assets/images/question-list/larnten-4.png differ diff --git a/src/assets/images/question-list/larnten-5.png b/src/assets/images/question-list/larnten-5.png new file mode 100644 index 0000000..bcdfe6e Binary files /dev/null and b/src/assets/images/question-list/larnten-5.png differ diff --git a/src/assets/images/question-list/larnten-6.png b/src/assets/images/question-list/larnten-6.png new file mode 100644 index 0000000..f21b928 Binary files /dev/null and b/src/assets/images/question-list/larnten-6.png differ diff --git a/src/assets/images/question-list/larnten-7.png b/src/assets/images/question-list/larnten-7.png new file mode 100644 index 0000000..af32f52 Binary files /dev/null and b/src/assets/images/question-list/larnten-7.png differ diff --git a/src/assets/images/question-list/larnten-8.png b/src/assets/images/question-list/larnten-8.png new file mode 100644 index 0000000..81a7f47 Binary files /dev/null and b/src/assets/images/question-list/larnten-8.png differ diff --git a/src/assets/images/question-list/larnten-9.png b/src/assets/images/question-list/larnten-9.png new file mode 100644 index 0000000..699b53a Binary files /dev/null and b/src/assets/images/question-list/larnten-9.png differ diff --git a/src/assets/images/question-list/left-arrow.png b/src/assets/images/question-list/left-arrow.png new file mode 100644 index 0000000..b76100a Binary files /dev/null and b/src/assets/images/question-list/left-arrow.png differ diff --git a/src/assets/images/question-list/right-arrow.png b/src/assets/images/question-list/right-arrow.png new file mode 100644 index 0000000..79e880f Binary files /dev/null and b/src/assets/images/question-list/right-arrow.png differ diff --git a/src/components/Index.vue b/src/components/Index.vue index 8aaec98..97a2d3c 100644 --- a/src/components/Index.vue +++ b/src/components/Index.vue @@ -184,7 +184,7 @@ const showVC = () => { .index-pet{ pointer-events: none; - @include pos(234px, 386px, 353px, 614px); + @include pos(378px, 452px, 187px, 614px); @include bg_pos("index/pet-icon.png"); } diff --git a/src/components/Question.vue b/src/components/Question.vue index a3d4e1a..a6c7335 100644 --- a/src/components/Question.vue +++ b/src/components/Question.vue @@ -7,64 +7,53 @@ import { useMainStore } from "@/store"; import { subAnswer } from "@/api"; // 页面配置初始化 -const emit = defineEmits(["QuestionPage"]); +const emit = defineEmits(["hide", "showResult"]); const userStore = useMainStore(); +const props = defineProps({ + questionId: { + default: 0, + required: true, + } +}) + // 当前题目 -const currentId = ref(0); //当前id 0~11 +const currentId = ref(props.questionId); //当前id 0~11 + + + const questionList = ref(data); //随机打乱题库 -const answerList = ref([]); // 答案库统计 -const activeId = ref(""); // 当前题目所选答案选项 -const showResultBtn = ref(false); const isChecked = ref(false) // 答题事件 const answerFn = (item, event) => { let e = event.target.parentElement; - activeId.value = item.aid; //更新选中状态 console.log('选项', item); - debounceTap(e, () => { - let cid = questionList.value[currentId.value].id; - let has = answerList.value.findIndex((obj) => obj.id === cid); - // 答案库中未存在该题的结果则新增,存在则更新最新选项 - if (has == -1) { - answerList.value.push({ - id: cid, - aid: item.aid, - answer: item.text, - }); - } else { - answerList.value[has].aid = item.aid; - answerList.value[has].answer = item.text; - } + console.log('当前题目:', currentId.value + 1); - + debounceTap(e, () => { gsap.set('.option-tips,.analysis', { autoAlpha: 1 }) gsap.set('.answer-box', { pointerEvents: 'none' }) isChecked.value = true - console.log('currentId.value',currentId.value); - if(currentId.value == 2 ){ + if (item.result === 'correct') { gsap.set('.create-btn', { display: 'block' }) - }else{ - gsap.set('.next-btn', { display: 'block' }) - + } else { + gsap.set('.return-btn', { display: 'block' }) } - }) } - // 下一题 const nextQuestion = (event) => { let e = event.target; debounceTap(e, () => { - isChecked.value = false - gsap.set('.option-tips,.analysis', { autoAlpha: 0 }) - currentId.value++ - activeId.value = '' - gsap.set('.answer-box', { pointerEvents: 'initial' }) - gsap.set('.next-btn', { display: 'none' }) + gsap.to('.question-box', { + duration: 0.5, autoAlpha: 0, scale: 0.3, onComplete: () => { + emit('hide') + } + + }) }) @@ -74,8 +63,9 @@ const nextQuestion = (event) => { const viewResult = (event) => { let e = event.target; debounceTap(e, () => { - // 随机生成海报id - userStore.updatePosterId(getRandomNumber([1, 2, 3])) + // 更新海报id + userStore.posterId = currentId.value + 1 + gsap.set('.question-box', { pointerEvents: 'none' }) Toast('答题结束') Toast.loading({ @@ -106,7 +96,7 @@ const viewResult = (event) => { Toast.clear() gsap.to('.QuestionPage', { duration: 0.5, autoAlpha: 0, onComplete: () => { - emit("QuestionPage", { action: "showResult" }); + emit("showResult", { pid: currentId.value }); } }) }, 1000) @@ -114,32 +104,19 @@ const viewResult = (event) => { }) } -// 从数组中随机生成一个数字 -const getRandomNumber = (arr) => { - var randomIndex = Math.floor(Math.random() * arr.length); - return arr[randomIndex]; -} - onMounted(() => { gsap.from('.question-bg', { duration: 0.5, autoAlpha: 0, }) gsap.from('.question-box', { duration: 0.5, scale: 0.4, autoAlpha: 0, }) gsap.to('.question-lantern-icon', { duration: 5, transformOrigin: '100% 0%', rotation: '10deg', repeat: -1, yoyo: true, ease: 'none' }) - }); @@ -194,26 +171,7 @@ onMounted(() => { .question-bg { @include pos(750px, 1624px, 0px, 50%); transform: translateY(-50%); - @include bg_pos('qa/bg.jpg'); - - .question-bottom-bg { - pointer-events: none; - @include box(750px, 393px); - position: absolute; - left: 0px; - bottom: 0px; - @include bg_pos("qa/bottom-bg.png"); - } - - .bottom-fan-1 { - @include pos(370px, 334px, 545px, 1022px); - @include bg_pos('index/fan-3.png'); - } - - .bottom-fan-2 { - @include pos(350px, 205px, 494px, 1128px); - @include bg_pos('index/fan-4.png'); - } + background-color: rgba($color: #000000, $alpha: 0.6); } @@ -223,29 +181,31 @@ onMounted(() => { @include flexCen(); .question-lantern-icon { - // pointer-events: none; + pointer-events: none; @include pos(349px, 443px, 489px, 49px); @include bg_pos('qa/lantern-icon.png'); } - .container-fan-1 { - pointer-events: none; - @include pos(235px, 574px, 0px, 60px); - @include bg_pos("index/fan-1.png"); - } - - .container-fan-2 { - pointer-events: none; - @include pos(316px, 317px, -205px, 405px); - @include bg_pos("index/fan-2.png"); - } .question-box { - @include pos(656px, 913px, 47px, 339px); + @include pos(616px, 873px, 68px, 350px); @include bg_pos("qa/question-box.png"); + + .answer-larnten { + @include pos(310px, 526px, -120px, -120px); + @include bg_pos('qa/lantern-icon.png'); + pointer-events: none + } + + .answer-baozhu { + @include pos(145px, 167px, 507px, 725px); + @include bg_pos('qa/baozhu.png'); + pointer-events: none + } + .qa-number { - @include pos(100px, 56px, 278px, 89px); + @include pos(100px, 56px, 255px, 79px); font-size: 40px; font-style: italic; color: #c61a1a; @@ -256,7 +216,7 @@ onMounted(() => { } .qa-question-box { - @include pos(570px, 700px, 43px, 194px); + @include pos(570px, 700px, 22px, 194px); display: flex; flex-direction: column; // justify-content: space-around; @@ -301,6 +261,9 @@ onMounted(() => { justify-content: space-between; height: 200px; + + + // 选中状态 .correct-bg { border: 1px solid rgb(255, 238, 186) !important; @@ -334,7 +297,8 @@ onMounted(() => { .answer { - @include box(476px, 92px); + @include box(350px, 92px); + position: relative; border-radius: 47.5px; border: 2px solid rgb(255, 225, 172); @@ -346,7 +310,7 @@ onMounted(() => { align-items: center; .click-area { - @include pos(476px, 92px, 0px, 0px); + @include pos(350px, 92px, 0px, 0px); border-radius: 47.5px; } @@ -369,7 +333,7 @@ onMounted(() => { .answer-text-box { - @include box(335px, 100%); + @include box(270px, 100%); font-family: 'HarmonyOS_Sans_SC_Regular'; color: #ffe2ad; font-size: 28px; @@ -394,13 +358,12 @@ onMounted(() => { // 解析样式 .analysis { - visibility: hidden; + // visibility: hidden; width: 95%; font-family: 'HarmonyOS_Sans_SC_Regular'; font-size: 20px; - color: #ffe2ad; + color: #ffffff; text-align: center; - // padding: 20px; height: 100px; display: flex; justify-content: center; @@ -408,17 +371,17 @@ onMounted(() => { flex-direction: column; } - .next-btn{ - @include box(234px,65px); - @include bg_pos("qa/next-btn.png"); + .return-btn { + @include box(246px, 73px); + @include bg_pos("qa/go-back.png"); display: none; } - .create-btn{ - @include box(234px,65px); + + .create-btn { + @include box(246px, 73px); @include bg_pos("qa/create-btn.png"); display: none; - } } @@ -430,11 +393,7 @@ onMounted(() => { @include bg_pos("qa/gold-icon.png"); } - .question-gold-icon-2 { - pointer-events: none; - @include pos(276px, 241px, -70px, 1089px); - @include bg_pos("qa/gold-icon-2.png"); - } + } } diff --git a/src/components/QuestionList.vue b/src/components/QuestionList.vue new file mode 100644 index 0000000..1f78486 --- /dev/null +++ b/src/components/QuestionList.vue @@ -0,0 +1,299 @@ + + + + + \ No newline at end of file diff --git a/src/components/Result.vue b/src/components/Result.vue index 308c5cb..ed8e758 100644 --- a/src/components/Result.vue +++ b/src/components/Result.vue @@ -2,7 +2,7 @@ import { gsap } from "gsap"; import { debounceTap } from "@/plugins"; import { useMainStore } from "@/store"; -import { posterCreate } from "@/plugins"; + import { Toast } from "vant"; import QRCode from "qrcode"; import { reactive } from "vue"; @@ -12,83 +12,92 @@ const emit = defineEmits(["ResultPage"]); const userStore = useMainStore(); const posterId = ref(userStore.posterId); //海报背景id:1~4 +console.log('海报id', posterId.value); + + 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, ]) // 生成二维码逻辑 const eqcodePic = ref(); -onMounted(() => { - console.log('posterId:',posterId.value); - let eqCodeUrl = import.meta.env.VITE_URL; - QRCode.toDataURL(eqCodeUrl) - .then((url) => { - eqcodePic.value = url; - // console.log("eq", eqcodePic.value); - }) - .catch((err) => { - console.error(err); - }); +onMounted(async () => { - gsap.from(".result-bg", { + // 执行任务队列 + 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) { + await posterCreate( + { width: 750, height: 1334 }, + [ + { name: "bg", src: posterImgList[posterId.value - 1], pos: { w: 750, h: 1334, x: 0, y: 0 } }, + { name: "eqcode", src: eqcodePic.value, pos: { w: 164, h: 164, x: 159, y: 1122 } }, + ] + ); + }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(".result-larnten-box", { + gsap.from(".poster-box", { duration: 0.7, scale: 1.4, autoAlpha: 0, }); - gsap.from(".result-larnten", { + gsap.from(".save-tips", { duration: 0.7, scale: 0.7, autoAlpha: 0, }); - gsap.from(".result-blessing-1", { + gsap.from(".go-draw", { duration: 0.7, y: -30, autoAlpha: 0, - delay:0.5 + delay: 0.5 }); - gsap.from(".result-blessing-2", { + gsap.from(".go-share", { duration: 0.7, y: -30, autoAlpha: 0, - delay:0.7 + delay: 0.7 }); - gsap.from(".result-product", { - duration: 0.7, - y: -30, - autoAlpha: 0, - delay:1 - }); - gsap.from(".result-tips", { - duration: 0.7, - y: -30, - autoAlpha: 0, - delay:1.2 - }); - gsap.from(".create-poster", { - duration: 0.7, - y: -30, - autoAlpha: 0, - delay:1.4, - onComplete:()=>{ - // gsap.to('.result-larnten',{duration:5,transformOrigin:'50% 0%',rotation:'10deg',repeat:-1,yoyo:true,ease:'none'}) - let gl = gsap.timeline({repeat:-1,yoyo:true}) - gl.to('.result-larnten',{duration:1,transformOrigin:'50% 0%',rotation:'3deg',ease:'none'}) - gl.to('.result-larnten',{duration:1,transformOrigin:'50% 0%',rotation:'0deg',ease:'none'}) - gl.to('.result-larnten',{duration:1,transformOrigin:'50% 0%',rotation:'-3deg',ease:'none'}) - // gsap.fo('.result-larnten',{duration:5,transformOrigin:'50% 0%',rotation:'10deg',repeat:-1,yoyo:true,ease:'none'}) - } - }); -}); +} + // 生成海报逻辑 const createPoster = (event) => { @@ -102,10 +111,10 @@ const createPoster = (event) => { // 背景 { name: "bg", - src: posterImgList[posterId.value-1], + src: posterImgList[posterId.value - 1], pos: { w: 750, h: 1334, x: 0, y: 0 }, }, - // 二维码 + // 二维码 { name: "eqcode", src: eqcodePic.value, @@ -115,7 +124,7 @@ const createPoster = (event) => { ); // gsap.to('.posterPop',{duration:0.5,autoAlpha:1}) - + }); }; @@ -135,7 +144,12 @@ const goDraw = (event) => { const hidePop = (event) => { let e = event.target; debounceTap(e, () => { - gsap.to(".posterPop", { duration: 0.5, autoAlpha: 0 }); + gsap.to(".posterPop", { + duration: 0.5, autoAlpha: 0, + onComplete: () => { + emit('ResultPage', { action: 'hide' }) + } + }); }); }; @@ -151,32 +165,87 @@ const goShare = (event) => { 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 => { + + // 图片素材遍历绘制 + 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 +} + +