0808 morning

This commit is contained in:
feie9456 2025-08-08 11:38:39 +08:00
parent a3c42d2e8c
commit 44f1c3fcee
9 changed files with 121 additions and 107 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 127 KiB

View File

@ -471,7 +471,7 @@ export interface QuizQuestion {
answers: string[]; // 正确答案(单选也使用数组,方便统一处理)
}
// ARC Retail 弹性福利平台答题竞赛题库
// ARC Retail 弹性福利平台答题竞赛题库 (更新版)
export const arcRetailQuiz: QuizQuestion[] = [
// --- 一、单选题 ---
{
@ -491,19 +491,19 @@ export const arcRetailQuiz: QuizQuestion[] = [
type: 'single',
question: '弹性福利平台上线后,健康福利的变化是?',
options: [
'只能选体检',
'可在体检和牙齿清洁中自主选择',
'同时免费领体检 + 洁牙',
'只有体检项目',
'可在体检和中自主选择',
'享有中医理疗',
'取消健康福利',
],
answers: ['可在体检和牙齿清洁中自主选择'],
answers: ['可在体检和中自主选择'],
},
{
id: 3,
type: 'single',
question: '员工想知道自己有多少福利积分,最便捷的方式是?',
options: [
'每月找 HR 查',
'店经理告知',
'登录弹性福利平台实时查看',
'等年底邮件通知',
'问同事打听',
@ -513,15 +513,15 @@ export const arcRetailQuiz: QuizQuestion[] = [
{
id: 4,
type: 'single',
question: '以下哪项是 2025 年 新增 的福利兑换项目?',
options: ['节日礼品', '员工洁牙', '法定社保', '商业保险'],
answers: ['员工洁牙'],
question: '以下哪项是弹性福利平台上线后,新增的福利项目?',
options: ['节日礼品', '员工洁牙', '法定社保', '商业保险'],
answers: ['员工洁牙'],
},
{
id: 5,
type: 'single',
question: '福利积分 主要通过什么方式获取?',
options: ['日常加班', '参与景仰计划', '绩效满分', '达成销售业绩'],
question: '福利积分通过什么方式获取?',
options: ['公益活动', '参与景仰计划', '绩效满分', '达成销售业绩'],
answers: ['参与景仰计划'],
},
{
@ -536,12 +536,12 @@ export const arcRetailQuiz: QuizQuestion[] = [
type: 'single',
question: '如果觉得近期压力大,心情低落,哪一项解决路径是公司平台提供的?',
options: [
'可以求助公司专业的EAP服务',
'可以求助公司专业的EAP服务 员工360关爱计划',
'和朋友吐苦水',
'大吃大喝',
'睡一觉',
],
answers: ['可以求助公司专业的EAP服务'],
answers: ['可以求助公司专业的EAP服务 员工360关爱计划'],
},
{
id: 8,

View File

@ -69,56 +69,12 @@ const giftProgress = ref(0); // max = giftList.length - 1
const timeSpent = ref(0)
const showEndAni = ref(false); //
const showShareMask = ref(false);
const leaderBoard = ref([
{
"name": "测试用户",
"time": 1.7116000000000005,
"region": "奥莱",
"store": "北京斯普瑞斯"
},
{
"name": "阿迪斯",
"time": 1.9645,
"region": "奥莱",
"store": "北京斯普瑞斯"
},
{
"name": "Mike",
"time": 45.5,
"region": "大北区",
"store": "大连恒隆广场"
},
{
"name": "小白",
"time": 83.2,
"region": "大西区",
"store": "太原万象城"
},
{
"name": "小明",
"time": 98.2,
"region": "大西区",
"store": "太原万象城"
},
{
"name": "Elena",
"time": 122.2,
"region": "大南区",
"store": "深圳湾万象城"
},
{
"name": "Elena2",
"time": 122.4,
"region": "大南区",
"store": "深圳湾万象城"
},
{
"name": "Elena3",
"time": 122.7,
"region": "大南区",
"store": "深圳湾万象城"
}
])
const leaderBoard = ref(Array(8).fill({
name: 'Loading...',
time: 0,
region: 'Loading...',
store: 'Loading...'
})); //
const showTitleIcon = ref(true)
async function shoot() {
@ -238,7 +194,7 @@ function gameLoop(currentTime = 0) {
await wait(500);
sunPos.value[1] = 124;
await wait(0);
await wait(100);
transitionOn.value = true;
while (sunPos.value[1] > 66) {
sunPos.value[1] -= SPEED * (deltaTime / 16.67) * 6;
@ -417,6 +373,10 @@ async function gameEnd() {
easing: 'ease-in-out',
fill: 'forwards',
}).finished
.then(() => {
sunEndEle.value?.jumpTo('进入');
showEndAni.value = true;
});
gameState.value = GAME_STATE.gameEnd;
@ -427,12 +387,6 @@ async function gameEnd() {
showTitleIcon.value = false;
});
await wait(1800)
showEndAni.value = true;
sunEndEle.value?.jumpTo('进入');
}
async function startQuiz() {
@ -527,8 +481,15 @@ async function handleFinishQuiz(time: number, choices: ('none' | 'selected' | 'c
}).then(_ => {
fetch('/api/score', {
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json()).then(data => leaderBoard.value = data);
})
}).then(res => res.json()).then(data => leaderBoard.value = data)
.catch(err => {
console.error('Error fetching leaderboard:', err);
alert('获取排行榜失败,请稍后再试。' + err.message);
});
}).catch(err => {
console.error('Error submitting score:', err);
alert('提交分数失败,请稍后再试。' + err.message);
});
await wait(1500);
sunEndEle.value?.jumpTo('向上进入')
@ -601,22 +562,23 @@ window.addEventListener('keydown', (e) => {
<div class="sun-ani-end-wrapper abs" style="pointer-events: none; inset: 0; width: 100%;z-index: 2;"
:style="{ display: showEndAni ? 'block' : 'none' }">
<AniEle :url="assets.ani.后段效果" :auto-play="false" ref="sun-ani-end" class="sun-ani-end" :height="2462" :width="1179" :rules="[
// 0 - 97
{ name: '进入', frame: 98, loop: 1, pauseAfter: false, duration: 33 },
// 98 - 129
{ name: '落下前循环', frame: 32, loop: 0, pauseAfter: true, duration: 33 },
// 130 - 161
{ name: '落下出屏幕', frame: 32, loop: 1, pauseAfter: true, duration: 33 },
// 162 - 227
{ name: '向上进入', frame: 66, loop: 1, pauseAfter: false, duration: 33 },
// 228 - 293
{ name: '左右循环', frame: 66, loop: 0, pauseAfter: true, duration: 33 },
// 294 - 326
{ name: '落下进蹦床', frame: 33, loop: 1, pauseAfter: false, duration: 33 },
// 327 - 358
{ name: '蹦床弹跳循环', frame: 32, loop: 0, pauseAfter: false, duration: 33 },
]" style="width: 100%; height: auto;" />
<AniEle :url="assets.ani.后段效果" :auto-play="false" ref="sun-ani-end" class="sun-ani-end" :height="2462"
:width="1179" :rules="[
// 0 - 97
{ name: '进入', frame: 98, loop: 1, pauseAfter: false, duration: 33 },
// 98 - 129
{ name: '落下前循环', frame: 32, loop: 0, pauseAfter: true, duration: 33 },
// 130 - 161
{ name: '落下出屏幕', frame: 32, loop: 1, pauseAfter: true, duration: 33 },
// 162 - 227
{ name: '向上进入', frame: 66, loop: 1, pauseAfter: false, duration: 33 },
// 228 - 293
{ name: '左右循环', frame: 66, loop: 0, pauseAfter: true, duration: 33 },
// 294 - 326
{ name: '落下进蹦床', frame: 33, loop: 1, pauseAfter: false, duration: 33 },
// 327 - 358
{ name: '蹦床弹跳循环', frame: 32, loop: 0, pauseAfter: false, duration: 33 },
]" style="width: 100%; height: auto;" />
</div>
<Transition name="fade">

View File

@ -22,23 +22,25 @@ QRCode.toDataURL(`https://arcteryx-game-demo.xn--876a.net`, {
console.error('生成二维码失败:', err);
});
const posterP1Ele = useTemplateRef('gui-ani-end-post-p1');
const posterP2Ele = useTemplateRef('gui-ani-end-post-p2');
const emit = defineEmits(['resetGame', 'showShareMask']);
const hasP2AnimationPlayed = ref(false);
const currentPosterIndex = ref(0);
onMounted(() => {
// Intersection Observer p2
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !hasP2AnimationPlayed.value) {
// p2
if (entry.isIntersecting) {
currentPosterIndex.value = 1; // p2
if (hasP2AnimationPlayed.value) return
hasP2AnimationPlayed.value = true;
posterP2Ele.value?.jumpTo('p2');
console.log('Poster P2 animation triggered');
//
observer.unobserve(entry.target);
}
});
}, {
@ -46,7 +48,7 @@ onMounted(() => {
rootMargin: '0px'
});
// p2
const p1Element = posterP1Ele.value?.$el;
const p2Element = posterP2Ele.value?.$el;
if (p2Element) {
observer.observe(p2Element);
@ -55,21 +57,45 @@ onMounted(() => {
console.warn('P2 element not found');
}
const observerP1 = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
currentPosterIndex.value = 0; // p1
}
});
}, {
threshold: 0.5, // 50%
rootMargin: '0px'
});
if (p1Element) {
observerP1.observe(p1Element);
console.log('Started observing P1 element');
} else {
console.warn('P1 element not found');
}
// 8p2p2
setTimeout(() => {
if (!hasP2AnimationPlayed.value) {
console.log('Auto scrolling to P2 after 8 seconds');
const posterContainer = document.querySelector('.poster-container');
if (posterContainer) {
// p250%
posterContainer.scrollTo({
left: posterContainer.scrollWidth * 0.5,
behavior: 'smooth'
});
}
scrollToPoster(1); // p2
}
}, 8000); // 8 = 8000
})
function scrollToPoster(index: number) {
const posterContainer = document.querySelector('.poster-container');
if (posterContainer) {
// p250%
posterContainer.scrollTo({
left: posterContainer.scrollWidth * 0.5 *index,
behavior: 'smooth'
});
}
}
</script>
<template>
@ -82,7 +108,7 @@ onMounted(() => {
style="position: absolute;top: 29.3%;left: 37.2%;width: 57.3%; height: 38%; overflow-x: auto; overflow-y: hidden; pointer-events: all; scroll-snap-type: x mandatory;">
<div class="poster-wrapper" style="display: flex; width: 200%; height: 100%; flex-direction: row;"
dir="ltr">
<AniEle :url="assets.ani.海报p1" ref="gui-ani-end-post-p1 "
<AniEle :url="assets.ani.海报p1" ref="gui-ani-end-post-p1"
style="width: 50%; flex-shrink: 0; scroll-snap-align: start;" class="gui-ani-end-post" :height="940"
:width="671" :rules="[
{ name: 'p1', frame: 32, loop: 1, pauseAfter: true, duration: 33 },
@ -95,16 +121,23 @@ onMounted(() => {
]" />
</div>
</div>
<div class="dot" style="position: absolute;top: 29.3%;left: 37.2%;width: 57.3%; height: 38%; ">
<div class="dot-item" @click="scrollToPoster(0)" :class="{ active: currentPosterIndex === 0 }"></div>
<div class="dot-item" @click="scrollToPoster(1)" :class="{ active: currentPosterIndex === 1 }"></div>
</div>
<AniEle :url="assets.ani.线" ref="gui-ani-end" class="gui-ani-end" :height="2462" :width="1179" :rules="[
{ name: 'all', frame: 54, loop: 1, pauseAfter: false, duration: 16 },
]" style="width: 100%; height: auto;position: absolute;inset: 0;pointer-events: none;" />
<img src="../../assets/game/床.webp" alt="" class="abs last-bed" style="width: 66vw;bottom: -19%;left: 17%;">
<img src="../../assets/game/分享海报.webp" alt="" class="abs" @click="AudioEffects.play('按钮音效'); emit('showShareMask')"
<img src="../../assets/game/分享海报.webp" alt="" class="abs"
@click="AudioEffects.play('按钮音效'); emit('showShareMask')"
style="width: 34vw;bottom: -19%;left: 15%;animation: last-btn-in 0.3s ease-out forwards; cursor: pointer; pointer-events: all;">
<img src="../../assets/game/再玩一次.webp" alt="" class="abs" @click="AudioEffects.play('按钮音效'); emit('resetGame')"
style="width: 34vw;bottom: -19%;left: 51%;animation: last-btn-in 0.3s ease-out forwards; cursor: pointer; animation-delay: 200ms; pointer-events: all;">
<div class="time-spent abs" style="left: 10%; top:44%;width: 24%;height: 23%; display: flex;
align-items: center; flex-direction: column;">
<div class="line-1"
@ -118,7 +151,7 @@ onMounted(() => {
<div class="time"
style="font-size: 10vw;animation: line-in 0.5s ease-out 0.8s forwards;transform: translateX(-230%);">
{{ timeSpent}}</div>
{{ timeSpent }}</div>
<img :src="qrcodeUrl" alt=""
style="width: 100%;bottom:7%;position: absolute;animation: line-in 0.5s ease-out 1s forwards;transform: translateX(-230%);">
@ -137,6 +170,26 @@ onMounted(() => {
</template>
<style lang="scss" scoped>
.dot {
transform: none;
align-items: flex-end;
justify-content: center;
padding-bottom: 1vw;
gap: 1vw;
}
.dot .dot-item {
background-color: #b2d8ff;
height: 1.5vw;
width: 1.5vw;
pointer-events: all;
cursor: pointer;
&.active {
background-color: #78b0e9;
}
}
.poster-container {
scrollbar-width: none;
@ -152,5 +205,4 @@ onMounted(() => {
.gui-ani-end-post {
object-fit: contain;
}
</style>

View File

@ -524,8 +524,8 @@ img {
}
.store-list-container {
margin-bottom: 12vw;
height: 35vh;
margin-bottom: 10vw;
height: 60vw;
overflow: hidden;
position: relative;
mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 85%, transparent 100%);