hookehuyr

feat(排行榜): 添加活动排行榜图标并优化切换动画和样式

为活动排行榜按钮添加图标并优化家庭排行榜页面的交互体验
- 在活动排行榜按钮前添加分类图标
- 实现平滑的标签切换动画和指示器
- 优化排名卡片和交互元素的悬停效果
- 调整排行榜布局和视觉细节
......@@ -83,6 +83,7 @@
<view class="px-5 mb-4 mt-4">
<view @tap="openFamilyRank" class="w-full bg-blue-500 text-white py-3 rounded-lg flex flex-col items-center justify-center">
<view class="flex items-center justify-center">
<Category size="16" class="mr-2" />
活动排行榜
</view>
</view>
......@@ -172,7 +173,7 @@
<script setup>
import { ref, computed, onMounted } from 'vue';
import Taro, { useDidShow } from '@tarojs/taro';
import { Setting, Photograph, Right, Close } from '@nutui/icons-vue-taro';
import { Setting, Photograph, Right, Close, Category } from '@nutui/icons-vue-taro';
import BottomNav from '../../components/BottomNav.vue';
import PointsCollector from '@/components/PointsCollector.vue'
import WeRunAuth from '@/components/WeRunAuth.vue'
......
<!--
* @Date: 2025-09-01 13:07:52
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-01 14:46:59
* @LastEditTime: 2025-09-01 16:05:41
* @FilePath: /lls_program/src/pages/FamilyRank/index.vue
* @Description: 文件描述
-->
......@@ -10,6 +10,11 @@
<!-- 顶部导航 -->
<view class="header">
<view class="nav-tabs">
<!-- 滑动指示器 -->
<view
class="tab-indicator"
:class="{ 'indicator-shanghai': activeTab === 'shanghai' }"
></view>
<view
class="tab-item"
:class="{ active: activeTab === 'huangpu' }"
......@@ -28,7 +33,7 @@
</view>
<!-- 排行榜内容 -->
<view class="rank-content">
<view class="rank-content" :class="{ 'content-switching': isContentSwitching }">
<!-- 前三名展示 -->
<view class="top-three">
<!-- 第二名 -->
......@@ -126,12 +131,28 @@ import { ref, computed } from 'vue'
// 当前激活的tab
const activeTab = ref('huangpu')
// 内容切换状态
const isContentSwitching = ref(false)
/**
* 切换tab
* @param {string} tab - tab名称
*/
const switchTab = (tab) => {
activeTab.value = tab
if (activeTab.value === tab) return
// 开始切换动画
isContentSwitching.value = true
// 延迟切换内容,让淡出动画先执行
setTimeout(() => {
activeTab.value = tab
// 内容切换后,结束切换状态,开始淡入动画
setTimeout(() => {
isContentSwitching.value = false
}, 50)
}, 200)
}
/**
......@@ -250,6 +271,25 @@ const myRank = ref({
border-radius: 60rpx;
padding: 8rpx;
margin: 0 80rpx;
position: relative;
overflow: hidden;
.tab-indicator {
position: absolute;
top: 8rpx;
left: 8rpx;
width: calc(50% - 8rpx);
height: calc(100% - 16rpx);
background: rgba(255, 255, 255, 1);
border-radius: 52rpx;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
z-index: 1;
&.indicator-shanghai {
transform: translateX(100%);
}
}
.tab-item {
flex: 1;
......@@ -260,12 +300,18 @@ const myRank = ref({
font-size: 28rpx;
font-weight: 500;
transition: all 0.3s ease;
position: relative;
z-index: 2;
cursor: pointer;
&.active {
background: rgba(255, 255, 255, 1);
color: #4A90E2;
font-weight: 600;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
transform: scale(1.02);
}
&:hover {
color: rgba(255, 255, 255, 1);
}
}
}
......@@ -273,6 +319,14 @@ const myRank = ref({
.rank-content {
padding: 0 40rpx;
transition: all 0.3s ease;
transform: translateY(0);
opacity: 1;
&.content-switching {
opacity: 0.3;
transform: translateY(-20rpx);
}
}
.top-three {
......@@ -281,7 +335,7 @@ const myRank = ref({
justify-content: center;
align-items: flex-end;
margin: 180rpx 0 0 0;
height: 400rpx;
height: 360rpx;
gap: -40rpx;
.rank-item {
......@@ -289,17 +343,22 @@ const myRank = ref({
flex-direction: column;
align-items: center;
position: relative;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
&:hover {
transform: translateY(-10rpx);
}
.crown {
font-size: 40rpx;
margin-bottom: 10rpx;
&.crown-gold {
filter: hue-rotate(45deg) brightness(1.2);
filter: grayscale(0.3) brightness(1.1);
}
&.crown-silver {
filter: grayscale(0.3) brightness(1.1);
filter: hue-rotate(45deg) brightness(1.2);
}
&.crown-bronze {
......@@ -377,7 +436,7 @@ const myRank = ref({
.rank-number {
width: 220rpx;
height: 200rpx;
height: 180rpx;
background: linear-gradient(135deg, #C0C0C0 0%, #A0A0A0 100%);
}
}
......@@ -395,7 +454,7 @@ const myRank = ref({
.rank-number {
width: 220rpx;
height: 260rpx;
height: 220rpx;
background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
}
}
......@@ -412,7 +471,7 @@ const myRank = ref({
.rank-number {
width: 220rpx;
height: 180rpx;
height: 160rpx;
background: linear-gradient(135deg, #CD7F32 0%, #B8860B 100%);
}
}
......@@ -433,6 +492,12 @@ const myRank = ref({
justify-content: space-between;
padding: 24rpx 32rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
&:hover {
background: rgba(74, 144, 226, 0.05);
transform: translateX(8rpx);
}
&:last-child {
border-bottom: none;
......@@ -505,6 +570,12 @@ const myRank = ref({
backdrop-filter: blur(10px);
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
z-index: 99;
transition: all 0.3s ease;
&:hover {
transform: translateY(-4rpx);
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.15);
}
.my-rank-content {
display: flex;
......