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 }" :style="{ height: bottomSectionHeight }"
> >
<div <div
style="display: flex; justify-content: center; align-items: center" style="display: flex; align-items: center; overflow: hidden; width: 100%"
:style="usernameAreaStyle" :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> </div>
</div> </div>
@ -166,7 +223,7 @@ const usernameAreaStyle = computed(() => {
case '2': case '2':
return 'height: 39%; width: 90%;' return 'height: 39%; width: 90%;'
case '3': case '3':
return 'height: 26%; width: 75%;' return 'height: 26%; width: 70%;'
case '4': case '4':
return 'height: 26%; width: 75%;' return 'height: 26%; width: 75%;'
case '5-7': case '5-7':
@ -182,6 +239,11 @@ const usernameAreaStyle = computed(() => {
const textSizeClass = computed(() => { const textSizeClass = computed(() => {
return props.ranking === '1' ? 'top1Text' : 'text' return props.ranking === '1' ? 'top1Text' : 'text'
}) })
//
const isTopOne = computed(() => {
return props.ranking === '1'
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -190,6 +252,14 @@ const textSizeClass = computed(() => {
color: black; color: black;
} }
.top1Text {
font-size: 0.75em;
}
.text {
font-size: 0.6em;
}
.showText { .showText {
color: #fff; color: #fff;
text-align: center; text-align: center;
@ -198,12 +268,26 @@ const textSizeClass = computed(() => {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.top1Text { .scroll-wrapper {
font-size: 0.75em; display: flex;
width: fit-content;
animation: scroll-left 5s linear infinite;
will-change: transform;
} }
.text { .scroll-content {
font-size: 0.6em; 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) { @media screen and (max-width: 360px) {

View File

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