2025-06-25 21:54:18 +08:00
|
|
|
|
<script setup>
|
2025-08-25 13:47:32 +08:00
|
|
|
|
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
|
2025-06-25 21:54:18 +08:00
|
|
|
|
const props = defineProps({
|
|
|
|
|
|
stopMatch: {
|
|
|
|
|
|
type: Function,
|
|
|
|
|
|
default: () => {},
|
|
|
|
|
|
},
|
|
|
|
|
|
onComplete: {
|
|
|
|
|
|
type: Function,
|
|
|
|
|
|
default: null,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
const playerNames = [
|
2025-10-28 16:44:15 +08:00
|
|
|
|
"乐正青山",
|
|
|
|
|
|
"宇文玉兰",
|
|
|
|
|
|
"岑思宇",
|
|
|
|
|
|
"邬梓瑜",
|
|
|
|
|
|
"范子衿",
|
2025-07-22 00:01:29 +08:00
|
|
|
|
"旗鼓相当的对手",
|
2025-10-28 16:44:15 +08:00
|
|
|
|
"乐子睿",
|
|
|
|
|
|
"时春晓",
|
|
|
|
|
|
"柏孤鸿",
|
|
|
|
|
|
"东宫锦瑟",
|
|
|
|
|
|
"段干流云",
|
2025-06-25 21:54:18 +08:00
|
|
|
|
];
|
2025-10-28 16:44:15 +08:00
|
|
|
|
const textStyles = [
|
|
|
|
|
|
{
|
|
|
|
|
|
color: "#fff9",
|
|
|
|
|
|
fontSize: "18px",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
color: "#fff",
|
|
|
|
|
|
fontSize: "22px",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
color: "#fed847",
|
|
|
|
|
|
fontSize: "30px",
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const rowHeight = 100 / 7;
|
|
|
|
|
|
const totalHeight = (playerNames.length / 7) * 100 + 7;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
|
2025-10-28 16:44:15 +08:00
|
|
|
|
const currentTop = ref(-totalHeight + rowHeight * 0);
|
2025-06-25 21:54:18 +08:00
|
|
|
|
const timer = ref(null);
|
|
|
|
|
|
|
2025-10-28 16:44:15 +08:00
|
|
|
|
const getTextStyle = (top, index) => {
|
|
|
|
|
|
const count = Math.floor(
|
|
|
|
|
|
((totalHeight + (top + rowHeight / 3)) / rowHeight).toFixed(1)
|
|
|
|
|
|
);
|
|
|
|
|
|
if (index === 12 - count) return textStyles[0];
|
|
|
|
|
|
else if (index === 13 - count) return textStyles[1];
|
|
|
|
|
|
else if (index === 14 - count) return textStyles[2];
|
|
|
|
|
|
else if (index === 15 - count) return textStyles[1];
|
|
|
|
|
|
else if (index === 16 - count) return textStyles[0];
|
|
|
|
|
|
return {
|
2025-06-25 21:54:18 +08:00
|
|
|
|
color: "#fff6",
|
2025-10-28 16:44:15 +08:00
|
|
|
|
fontSize: "14px",
|
|
|
|
|
|
};
|
2025-06-25 21:54:18 +08:00
|
|
|
|
};
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => props.onComplete,
|
2025-11-08 12:18:34 +08:00
|
|
|
|
(newVal) => {
|
|
|
|
|
|
if (timer.value) {
|
|
|
|
|
|
clearInterval(timer.value);
|
|
|
|
|
|
timer.value = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
timer.value = setInterval(() => {
|
|
|
|
|
|
const count = Math.round(
|
|
|
|
|
|
(
|
|
|
|
|
|
(totalHeight + (currentTop.value + rowHeight / 3)) /
|
|
|
|
|
|
rowHeight
|
|
|
|
|
|
).toFixed(1)
|
|
|
|
|
|
);
|
|
|
|
|
|
if (count === 10) {
|
2025-10-28 16:44:15 +08:00
|
|
|
|
clearInterval(timer.value);
|
|
|
|
|
|
timer.value = null;
|
2025-11-08 12:18:34 +08:00
|
|
|
|
setTimeout(newVal, 1500);
|
|
|
|
|
|
return;
|
2025-10-28 16:44:15 +08:00
|
|
|
|
}
|
2025-11-08 12:18:34 +08:00
|
|
|
|
// 这里不重置,如果运行超13秒,就不会循环了
|
|
|
|
|
|
if (currentTop.value >= -4) {
|
|
|
|
|
|
currentTop.value = -totalHeight;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
currentTop.value += 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 40);
|
2025-06-25 21:54:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
timer.value = setInterval(() => {
|
2025-10-28 16:44:15 +08:00
|
|
|
|
if (currentTop.value >= -4) {
|
|
|
|
|
|
currentTop.value = -totalHeight;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
} else {
|
2025-10-28 16:44:15 +08:00
|
|
|
|
currentTop.value += 2;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
}
|
2025-06-26 13:41:40 +08:00
|
|
|
|
}, 40);
|
2025-06-25 21:54:18 +08:00
|
|
|
|
});
|
2025-08-25 13:47:32 +08:00
|
|
|
|
onBeforeUnmount(() => {
|
2025-06-25 21:54:18 +08:00
|
|
|
|
if (timer.value) clearInterval(timer.value);
|
2025-10-28 16:44:15 +08:00
|
|
|
|
timer.value = null;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<view class="matching">
|
|
|
|
|
|
<image
|
|
|
|
|
|
src="../static/matching-bg.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
class="matching-bg"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view>
|
2025-10-28 16:44:15 +08:00
|
|
|
|
<view class="player-names" :style="{ top: `${currentTop}%` }">
|
2025-06-25 21:54:18 +08:00
|
|
|
|
<text
|
2025-10-28 16:44:15 +08:00
|
|
|
|
v-for="(name, index) in [...playerNames, ...playerNames]"
|
2025-06-25 21:54:18 +08:00
|
|
|
|
:key="index"
|
|
|
|
|
|
:style="{
|
2025-10-28 16:44:15 +08:00
|
|
|
|
lineHeight: `${rowHeight}vw`,
|
|
|
|
|
|
...getTextStyle(currentTop, index),
|
2025-06-25 21:54:18 +08:00
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ name }}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<button hover-class="none" @click="stopMatch">取消匹配</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.matching {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
.matching > view {
|
|
|
|
|
|
width: 70vw;
|
2025-06-26 01:27:23 +08:00
|
|
|
|
height: 95vw;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
overflow: hidden;
|
2025-06-26 13:41:40 +08:00
|
|
|
|
position: absolute;
|
2025-10-28 16:44:15 +08:00
|
|
|
|
top: 30vw;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
.matching-bg {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
width: 70vw;
|
|
|
|
|
|
height: 102vw;
|
2025-06-26 01:27:23 +08:00
|
|
|
|
top: 27vw;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
.matching > button {
|
|
|
|
|
|
width: 55%;
|
|
|
|
|
|
padding: 18px;
|
|
|
|
|
|
color: #000;
|
|
|
|
|
|
background-color: #fed847;
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
border-radius: 30px;
|
2025-06-26 13:41:40 +08:00
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 142vw;
|
2025-06-25 21:54:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
.player-names {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.player-names > text {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|