201 lines
4.0 KiB
Vue
201 lines
4.0 KiB
Vue
<template>
|
||
<view class="podium-card" :class="['podium-' + rank]" @click="handleClick">
|
||
<!-- 藏品主图(不规则圆角) -->
|
||
<view class="cover-wrap">
|
||
<!-- 相框(最底层) -->
|
||
<image
|
||
class="podium-frame"
|
||
:src="`/static/square/galaxy/LV${rank}.png`"
|
||
mode="aspectFit"
|
||
/>
|
||
<image
|
||
class="cover-image"
|
||
:src="item.cover_url || item.cover_image || ''"
|
||
mode="aspectFill"
|
||
/>
|
||
</view>
|
||
|
||
<!-- TOP N 标签(cover 下方居中) -->
|
||
<view class="top-label">TOP {{ rank }}</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
const props = defineProps({
|
||
item: { type: Object, required: true },
|
||
rank: { type: Number, required: true, validator: (v) => v >= 1 && v <= 3 },
|
||
});
|
||
|
||
const emit = defineEmits(["cardClick"]);
|
||
|
||
function handleClick() {
|
||
emit("cardClick", props.item);
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.podium-card {
|
||
position: absolute;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 60vw;
|
||
height: 320rpx;
|
||
}
|
||
|
||
/* TOP 1: 中央大卡(最大) */
|
||
.podium-1 {
|
||
top: 400rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
animation: podium-float-center 3s ease-in-out infinite;
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background-image: url("/static/square/galaxy/topbj1.png");
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
opacity: 0.95;
|
||
transform: scale(1.15);
|
||
}
|
||
.cover-wrap {
|
||
width: 144rpx;
|
||
height: 240rpx;
|
||
bottom: 136rpx;
|
||
left: 32rpx;
|
||
.podium-frame {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
.top-label{
|
||
left: 58%;
|
||
}
|
||
}
|
||
|
||
/* TOP 2: 左上 */
|
||
.podium-2 {
|
||
top: 184rpx;
|
||
left: -96rpx;
|
||
animation: podium-float 3.4s ease-in-out infinite;
|
||
animation-delay: -1.2s;
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background-image: url("/static/square/galaxy/topbj2.png");
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
opacity: 0.95;
|
||
transform: rotate(-14deg) scale(0.85);
|
||
}
|
||
.cover-wrap {
|
||
width: 144rpx;
|
||
height: 240rpx;
|
||
bottom: 72rpx;
|
||
.podium-frame {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* TOP 3: 右上 */
|
||
.podium-3 {
|
||
top: 152rpx;
|
||
right: -96rpx;
|
||
animation: podium-float 3.2s ease-in-out infinite;
|
||
animation-delay: -2s;
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background-image: url("/static/square/galaxy/topbj3.png");
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
opacity: 0.95;
|
||
transform: scale(0.85);
|
||
}
|
||
.cover-wrap {
|
||
width: 160rpx;
|
||
height: 180rpx;
|
||
bottom: 72rpx;
|
||
.podium-frame {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.podium-frame {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
z-index: 2;
|
||
pointer-events: none;
|
||
transform: scale(1.5);
|
||
}
|
||
|
||
.cover-wrap {
|
||
position: relative;
|
||
z-index: 2;
|
||
}
|
||
|
||
.cover-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
}
|
||
|
||
.top-label {
|
||
width: 64rpx;
|
||
position: absolute;
|
||
bottom: 48rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
color: #fffabd;
|
||
font-size: 20rpx;
|
||
font-weight: 800;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-shadow: -1px 1px 4px #ce0909d6;
|
||
background: linear-gradient(
|
||
93.1deg,
|
||
rgba(224, 180, 247, 0.71) -12.06%,
|
||
rgba(178, 246, 204, 0.71) 52.09%,
|
||
rgba(98, 178, 244, 0.71) 163.5%
|
||
);
|
||
backdrop-filter: blur(11.699999809265137px);
|
||
z-index: 7;
|
||
padding: 0 16rpx;
|
||
}
|
||
|
||
/* 上下浮动动画:podium-1 需保留 translateX(-50%) 居中,单独一组 keyframes */
|
||
@keyframes podium-float-center {
|
||
0%,
|
||
100% {
|
||
transform: translateX(-50%) translateY(0);
|
||
}
|
||
50% {
|
||
transform: translateX(-50%) translateY(-12rpx);
|
||
}
|
||
}
|
||
|
||
@keyframes podium-float {
|
||
0%,
|
||
100% {
|
||
transform: translateY(0);
|
||
}
|
||
50% {
|
||
transform: translateY(-10rpx);
|
||
}
|
||
}
|
||
</style>
|