feat(游戏王活动): 新增名称滚动效果

This commit is contained in:
hzj 2025-12-18 20:29:32 +08:00
parent dfa6833391
commit 5347b0042c
2 changed files with 125 additions and 19 deletions

View File

@ -50,11 +50,68 @@
:style="{ height: bottomSectionHeight }"
>
<div
style="display: flex; justify-content: center; align-items: center"
style="display: flex; align-items: center; overflow: hidden; width: 100%"
:style="usernameAreaStyle"
>
<div style="font-weight: 700" class="showText" :class="textSizeClass">
{{ name }}
<!-- 滚动容器 -->
<div class="scroll-wrapper">
<!-- 第一套内容 -->
<div class="scroll-content">
<div
style="color: #fff; font-weight: 700; white-space: nowrap"
:class="textSizeClass"
>
{{ name }}
</div>
<img
v-smart-img
src="/src/assets/icon/coin.png"
alt=""
style="display: block; width: 1.1em"
/>
<div
style="
font-weight: 700;
background: linear-gradient(180deg, #ffe656 0%, #fff 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
"
class="showText"
:class="isTopOne ? 'top1Text' : 'text'"
>
{{ distributionValue }}
</div>
</div>
<!-- 第二套内容间隔30px -->
<div class="scroll-content" style="margin-left: 30px">
<div
style="color: #fff; font-weight: 700; white-space: nowrap"
:class="textSizeClass"
>
{{ name }}
</div>
<img
v-smart-img
src="/src/assets/icon/coin.png"
alt=""
style="display: block; width: 1.1em"
/>
<div
style="
font-weight: 700;
background: linear-gradient(180deg, #ffe656 0%, #fff 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
"
class="showText"
:class="isTopOne ? 'top1Text' : 'text'"
>
{{ distributionValue }}
</div>
</div>
</div>
</div>
</div>
@ -166,7 +223,7 @@ const usernameAreaStyle = computed(() => {
case '2':
return 'height: 39%; width: 90%;'
case '3':
return 'height: 26%; width: 75%;'
return 'height: 26%; width: 70%;'
case '4':
return 'height: 26%; width: 75%;'
case '5-7':
@ -182,6 +239,11 @@ const usernameAreaStyle = computed(() => {
const textSizeClass = computed(() => {
return props.ranking === '1' ? 'top1Text' : 'text'
})
//
const isTopOne = computed(() => {
return props.ranking === '1'
})
</script>
<style lang="scss" scoped>
@ -190,6 +252,14 @@ const textSizeClass = computed(() => {
color: black;
}
.top1Text {
font-size: 0.75em;
}
.text {
font-size: 0.6em;
}
.showText {
color: #fff;
text-align: center;
@ -198,12 +268,26 @@ const textSizeClass = computed(() => {
text-overflow: ellipsis;
}
.top1Text {
font-size: 0.75em;
.scroll-wrapper {
display: flex;
width: fit-content;
animation: scroll-left 5s linear infinite;
will-change: transform;
}
.text {
font-size: 0.6em;
.scroll-content {
display: flex;
align-items: center;
gap: 4px;
}
@keyframes scroll-left {
0% {
transform: translateX(0);
}
100% {
transform: translateX(calc(-50% - 15px));
}
}
@media screen and (max-width: 360px) {

View File

@ -15,6 +15,7 @@
:BorderImgUrl="imageUrl('top1')"
:avatarUrl="RankingHasTop10[0].avatar"
:name="RankingHasTop10[0].nickname"
:distributionValue="RankingHasTop10[0].quantity || ''"
style="width: 55%"
@click="viewUserInfo(RankingHasTop10[0].userId)"
/>
@ -128,6 +129,7 @@
:BorderImgUrl="imageUrl('top2')"
:avatarUrl="RankingHasTop10[1].avatar"
:name="RankingHasTop10[1].nickname"
:distributionValue="RankingHasTop10[1].quantity || ''"
style="width: 40%"
@click="viewUserInfo(RankingHasTop10[1].userId)"
/>
@ -139,6 +141,7 @@
:BorderImgUrl="imageUrl('top3')"
:avatarUrl="RankingHasTop10[2].avatar"
:name="RankingHasTop10[2].nickname"
:distributionValue="RankingHasTop10[2].quantity || ''"
style="width: 38%"
@click="viewUserInfo(RankingHasTop10[2].userId)"
/>
@ -147,6 +150,7 @@
:BorderImgUrl="imageUrl('top4')"
:avatarUrl="RankingHasTop10[3].avatar"
:name="RankingHasTop10[3].nickname"
:distributionValue="RankingHasTop10[3].quantity || ''"
style="width: 38%"
@click="viewUserInfo(RankingHasTop10[3].userId)"
/>
@ -168,6 +172,7 @@
:BorderImgUrl="imageUrl('top5_7')"
:avatarUrl="topUser.avatar"
:name="topUser.nickname"
:distributionValue="topUser.quantity || ''"
style="width: 30%"
@click="viewUserInfo(topUser.userId)"
/>
@ -182,6 +187,7 @@
:BorderImgUrl="imageUrl('top8_10')"
:avatarUrl="topUser.avatar"
:name="topUser.nickname"
:distributionValue="topUser.quantity || ''"
style="width: 30%"
@click="viewUserInfo(topUser.userId)"
/>
@ -626,23 +632,39 @@ const showRanking = computed(() => {
// return []
})
// 5
//
const getNextMondayInBeijing = () => {
const now = new Date()
const beijingDay = (now.getUTCDay() + 6) % 7
// UTC (0=, 1=, ..., 6=) (0=, 6=)
//
const targetDate = new Date(now.getTime())
//
const daysToAdd = beijingDay === 0 ? 7 : 7 - beijingDay
const nextMondayBeijing = new Date(now)
//
const utcTime = now.getTime() + now.getTimezoneOffset() * 60000
const beijingTime = new Date(utcTime + 8 * 3600000) // UTC+8
//
nextMondayBeijing.setUTCDate(now.getUTCDate() + daysToAdd)
const beijingDay = beijingTime.getDay() // 0=, 1=, ..., 6=
const beijingHour = beijingTime.getHours()
// 5 (UTC21)
nextMondayBeijing.setUTCHours(21, 0, 0, 0)
// 0=, 1=, ..., 6=
const normalizedDay = beijingDay === 0 ? 6 : beijingDay - 1
return nextMondayBeijing.getTime()
let daysToAdd
if (normalizedDay === 0) {
//
if (beijingHour >= 5) {
daysToAdd = 7 //
} else {
daysToAdd = 0 //
}
} else {
daysToAdd = 7 - normalizedDay //
}
//
targetDate.setDate(targetDate.getDate() + daysToAdd)
targetDate.setHours(5, 0, 0, 0) // 5
return targetDate.getTime()
}
const targetTime = ref(getNextMondayInBeijing()) // ()