feat(stargalaxy): add LV1-12 frame images to podium and scattered items
This commit is contained in:
parent
dd5f95d734
commit
f66be49384
@ -1,5 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="podium-card" :class="['podium-' + rank]" :style="cardStyle" @click="handleClick">
|
<view class="podium-card" :class="['podium-' + rank]" :style="cardStyle" @click="handleClick">
|
||||||
|
<!-- 相框(最底层) -->
|
||||||
|
<image
|
||||||
|
class="podium-frame"
|
||||||
|
:src="frameSrc"
|
||||||
|
mode="aspectFit"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 钻石渐变外框 -->
|
<!-- 钻石渐变外框 -->
|
||||||
<view class="diamond-frame" :style="frameStyle"></view>
|
<view class="diamond-frame" :style="frameStyle"></view>
|
||||||
|
|
||||||
@ -18,7 +25,7 @@
|
|||||||
<view class="diamond-border"></view>
|
<view class="diamond-border"></view>
|
||||||
|
|
||||||
<!-- 皇冠(仅 TOP 1) -->
|
<!-- 皇冠(仅 TOP 1) -->
|
||||||
<view v-if="rank === 4" class="crown">👑</view>
|
<!-- <view v-if="rank === 4" class="crown">👑</view> -->
|
||||||
|
|
||||||
<!-- TOP N 标签(cover 下方居中) -->
|
<!-- TOP N 标签(cover 下方居中) -->
|
||||||
<view class="top-label" :style="labelStyle">TOP {{ displayRank }}</view>
|
<view class="top-label" :style="labelStyle">TOP {{ displayRank }}</view>
|
||||||
@ -39,6 +46,12 @@ const emit = defineEmits(['cardClick'])
|
|||||||
// 内部 rank 4/5/6 对外显示 1/2/3(颁奖台:TOP 1/2/3)
|
// 内部 rank 4/5/6 对外显示 1/2/3(颁奖台:TOP 1/2/3)
|
||||||
const displayRank = computed(() => props.rank - 3)
|
const displayRank = computed(() => props.rank - 3)
|
||||||
|
|
||||||
|
// 相框图片源:rank 4 → LV1, rank 5 → LV2, rank 6 → LV3
|
||||||
|
const frameSrc = computed(() => {
|
||||||
|
const lvNumber = props.rank - 3
|
||||||
|
return `/static/square/galaxy/LV${lvNumber}.png`
|
||||||
|
})
|
||||||
|
|
||||||
// 不同 rank 的标签渐变
|
// 不同 rank 的标签渐变
|
||||||
const labelGradients = {
|
const labelGradients = {
|
||||||
4: 'radial-gradient(ellipse, #FFD700, #FFF6A8 30%, #DAA520 100%)', // 金
|
4: 'radial-gradient(ellipse, #FFD700, #FFF6A8 30%, #DAA520 100%)', // 金
|
||||||
@ -88,12 +101,22 @@ function handleClick() {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.podium-frame {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.diamond-frame {
|
.diamond-frame {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
border-radius: 8rpx 44rpx 8rpx 38rpx;
|
border-radius: 8rpx 44rpx 8rpx 38rpx;
|
||||||
filter: blur(6rpx);
|
filter: blur(6rpx);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover-wrap {
|
.cover-wrap {
|
||||||
@ -103,6 +126,7 @@ function handleClick() {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
box-shadow: 4rpx 4rpx 28rpx rgba(127, 7, 7, 0.5);
|
box-shadow: 4rpx 4rpx 28rpx rgba(127, 7, 7, 0.5);
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover-image {
|
.cover-image {
|
||||||
@ -132,6 +156,7 @@ function handleClick() {
|
|||||||
-webkit-mask-composite: xor;
|
-webkit-mask-composite: xor;
|
||||||
mask-composite: exclude;
|
mask-composite: exclude;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.crown {
|
.crown {
|
||||||
@ -141,7 +166,7 @@ function handleClick() {
|
|||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
font-size: 44rpx;
|
font-size: 44rpx;
|
||||||
animation: crownPulse 2s ease-in-out infinite;
|
animation: crownPulse 2s ease-in-out infinite;
|
||||||
z-index: 5;
|
z-index: 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-label {
|
.top-label {
|
||||||
@ -157,7 +182,7 @@ function handleClick() {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
text-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.5);
|
text-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.5);
|
||||||
box-shadow: 0 6rpx 16rpx rgba(255, 140, 0, 0.5);
|
box-shadow: 0 6rpx 16rpx rgba(255, 140, 0, 0.5);
|
||||||
z-index: 6;
|
z-index: 7;
|
||||||
letter-spacing: 1rpx;
|
letter-spacing: 1rpx;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="scattered-ranks">
|
<view class="scattered-ranks">
|
||||||
<!-- 椭圆轨道装饰(虚线) -->
|
<!-- 椭圆轨道装饰(虚线) -->
|
||||||
<svg class="orbit-svg" viewBox="0 0 375 170" preserveAspectRatio="none">
|
<!-- <svg class="orbit-svg" viewBox="0 0 375 170" preserveAspectRatio="none">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="sg-orbit-grad" x1="0%" y1="0%" x2="0%" y2="100%">
|
<linearGradient id="sg-orbit-grad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
<stop offset="0%" stop-color="rgba(255,255,255,0.15)" />
|
<stop offset="0%" stop-color="rgba(255,255,255,0.15)" />
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<ellipse cx="187" cy="55" rx="80" ry="35" fill="url(#sg-center-glow)" />
|
<ellipse cx="187" cy="55" rx="80" ry="35" fill="url(#sg-center-glow)" />
|
||||||
<ellipse cx="187" cy="55" rx="130" ry="55" fill="none" stroke="url(#sg-orbit-grad)" stroke-width="1.5" stroke-dasharray="3,3" />
|
<ellipse cx="187" cy="55" rx="130" ry="55" fill="none" stroke="url(#sg-orbit-grad)" stroke-width="1.5" stroke-dasharray="3,3" />
|
||||||
<path d="M 57,55 A 130,55 0 0,0 317,55" stroke="rgba(255,250,189,0.85)" stroke-width="2.5" fill="none" />
|
<path d="M 57,55 A 130,55 0 0,0 317,55" stroke="rgba(255,250,189,0.85)" stroke-width="2.5" fill="none" />
|
||||||
</svg>
|
</svg> -->
|
||||||
|
|
||||||
<!-- 9 个散落 item -->
|
<!-- 9 个散落 item -->
|
||||||
<view
|
<view
|
||||||
@ -27,6 +27,12 @@
|
|||||||
:style="ringItemStyle(p)"
|
:style="ringItemStyle(p)"
|
||||||
@click="handleClick(items[i])"
|
@click="handleClick(items[i])"
|
||||||
>
|
>
|
||||||
|
<!-- 相框(最底层) -->
|
||||||
|
<image
|
||||||
|
class="ring-frame"
|
||||||
|
:src="ringFrameSrc(p.rank)"
|
||||||
|
mode="aspectFit"
|
||||||
|
/>
|
||||||
<view class="top-label">{{ formatLabel(p.rank) }}</view>
|
<view class="top-label">{{ formatLabel(p.rank) }}</view>
|
||||||
<image
|
<image
|
||||||
class="cover-image"
|
class="cover-image"
|
||||||
@ -83,6 +89,11 @@ function formatLabel(rank) {
|
|||||||
return 'TOP ' + rank
|
return 'TOP ' + rank
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ringFrameSrc(rank) {
|
||||||
|
const lvNumber = rank - 3 // rank 4 → LV1, ..., rank 12 → LV9
|
||||||
|
return `/static/square/galaxy/LV${lvNumber}.png`
|
||||||
|
}
|
||||||
|
|
||||||
function handleClick(item) {
|
function handleClick(item) {
|
||||||
if (item) emit('cardClick', item)
|
if (item) emit('cardClick', item)
|
||||||
}
|
}
|
||||||
@ -118,6 +129,15 @@ function handleClick(item) {
|
|||||||
animation: orbit 36s linear infinite;
|
animation: orbit 36s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ring-frame {
|
||||||
|
position: absolute;
|
||||||
|
inset: -2rpx; /* extend slightly outside the item bounds */
|
||||||
|
width: calc(100% + 4rpx);
|
||||||
|
height: calc(100% + 4rpx);
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.top-label {
|
.top-label {
|
||||||
width: 46rpx;
|
width: 46rpx;
|
||||||
height: 14rpx;
|
height: 14rpx;
|
||||||
@ -130,6 +150,7 @@ function handleClick(item) {
|
|||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
color: #FFFABD;
|
color: #FFFABD;
|
||||||
text-shadow: -1rpx 1rpx 2rpx rgba(206, 9, 9, 0.84);
|
text-shadow: -1rpx 1rpx 2rpx rgba(206, 9, 9, 0.84);
|
||||||
|
z-index: 2; /* above frame */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TOP 4 label 是金渐变(最显眼) */
|
/* TOP 4 label 是金渐变(最显眼) */
|
||||||
@ -145,6 +166,7 @@ function handleClick(item) {
|
|||||||
height: 56rpx;
|
height: 56rpx;
|
||||||
border-radius: 5rpx;
|
border-radius: 5rpx;
|
||||||
box-shadow: 3rpx 3rpx 6rpx rgba(198, 13, 13, 0.45);
|
box-shadow: 3rpx 3rpx 6rpx rgba(198, 13, 13, 0.45);
|
||||||
|
z-index: 1; /* between frame and label */
|
||||||
}
|
}
|
||||||
|
|
||||||
.r0 .cover-image {
|
.r0 .cover-image {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user