Commit 4f00d7595c578dbd30c86913a13f65eb16ee99ac
1 parent
844ae2b7
优化个人中心页面:实现玻璃态卡片效果、3D悬浮动效和流动导航指示器
- 增强玻璃态卡片效果:半透明背景+模糊效果+精致边框+内层高光 - 添加3D悬浮动效:所有卡片支持点击缩放和阴影变化,光晕扫过动画 - 优化底部导航栏:胶囊式设计+流动选中指示器,平滑过渡动画 - 提升整体视觉体验:轻盈高级的玻璃质感,流畅的交互动效
Showing
2 changed files
with
167 additions
and
21 deletions
绿纤uni-app/components/custom-tab-bar/index.vue
| 1 | 1 | <template> |
| 2 | 2 | <view class="tab-block"> |
| 3 | 3 | <view class='tab-list flex flex-center' :class="showMiddleButton === true?'tab-list-middle':'tab-list-default'"> |
| 4 | + <!-- 流动选中指示器 --> | |
| 5 | + <view class="tab-indicator" :style="{ left: indicatorLeft + 'px', width: indicatorWidth + 'px' }"></view> | |
| 4 | 6 | <view v-for="(item, index) in tabList" |
| 5 | 7 | :class="'list-item flex flex-column flex-middle ' + item.middleClass" |
| 6 | 8 | @tap="handlePush(item, index)" |
| 7 | - :key="index"> | |
| 9 | + :key="index" | |
| 10 | + :ref="'tabItem' + index"> | |
| 8 | 11 | <view class="item-img-box"> |
| 9 | 12 | <image |
| 10 | 13 | class="item-img" |
| ... | ... | @@ -84,7 +87,42 @@ |
| 84 | 87 | return matchedIndex >= 0 ? matchedIndex : 0; |
| 85 | 88 | } |
| 86 | 89 | }, |
| 90 | + mounted() { | |
| 91 | + this.updateIndicator() | |
| 92 | + }, | |
| 93 | + watch: { | |
| 94 | + currentTabIndex() { | |
| 95 | + this.$nextTick(() => { | |
| 96 | + setTimeout(() => { | |
| 97 | + this.updateIndicator() | |
| 98 | + }, 100) | |
| 99 | + }) | |
| 100 | + } | |
| 101 | + }, | |
| 87 | 102 | methods: { |
| 103 | + // 更新流动指示器位置 | |
| 104 | + updateIndicator() { | |
| 105 | + this.$nextTick(() => { | |
| 106 | + try { | |
| 107 | + const query = uni.createSelectorQuery().in(this) | |
| 108 | + query.select('.tab-list').boundingClientRect((tabListRect) => { | |
| 109 | + query.selectAll('.list-item').boundingClientRect((rects) => { | |
| 110 | + if (rects && rects.length > 0 && this.currentTabIndex >= 0 && this.currentTabIndex < rects.length) { | |
| 111 | + const currentRect = rects[this.currentTabIndex] | |
| 112 | + | |
| 113 | + if (currentRect && tabListRect) { | |
| 114 | + // 计算指示器的位置和宽度 | |
| 115 | + this.indicatorWidth = currentRect.width * 0.6 | |
| 116 | + this.indicatorLeft = currentRect.left - tabListRect.left + (currentRect.width - this.indicatorWidth) / 2 | |
| 117 | + } | |
| 118 | + } | |
| 119 | + }).exec() | |
| 120 | + }).exec() | |
| 121 | + } catch (e) { | |
| 122 | + console.error('更新指示器失败:', e) | |
| 123 | + } | |
| 124 | + }) | |
| 125 | + }, | |
| 88 | 126 | // 点击按钮 |
| 89 | 127 | handlePush(item, index) { |
| 90 | 128 | if (this.currentTabIndex !== index) { |
| ... | ... | @@ -134,29 +172,60 @@ |
| 134 | 172 | .tab-list{ |
| 135 | 173 | height: 120rpx; |
| 136 | 174 | } |
| 137 | - .tab-list-default{ | |
| 138 | - background-color: rgba(255, 255, 255, 0.85); | |
| 139 | - border-radius: 28rpx; | |
| 140 | - box-shadow: 0rpx 4rpx 20rpx rgba(0, 0, 0, 0.1); | |
| 141 | - backdrop-filter: blur(10rpx); | |
| 142 | - } | |
| 175 | + .tab-list-default{ | |
| 176 | + background: rgba(255, 255, 255, 0.7); | |
| 177 | + backdrop-filter: blur(20px) saturate(180%); | |
| 178 | + -webkit-backdrop-filter: blur(20px) saturate(180%); | |
| 179 | + border-radius: 28rpx; | |
| 180 | + box-shadow: 0rpx 8rpx 32rpx rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(255, 255, 255, 0.3) inset; | |
| 181 | + border: 1px solid rgba(255, 255, 255, 0.4); | |
| 182 | + position: relative; | |
| 183 | + transition: all 0.3s ease; | |
| 184 | + } | |
| 143 | 185 | .tab-list-middle { |
| 144 | 186 | position: relative; |
| 145 | 187 | background: url('https://res.paquapp.com/popmartvip/home/nav_bar_bg_2x.png') no-repeat center center; |
| 146 | 188 | background-size: cover; |
| 147 | 189 | } |
| 190 | + /* 流动选中指示器 */ | |
| 191 | + .tab-indicator { | |
| 192 | + position: absolute; | |
| 193 | + bottom: 8rpx; | |
| 194 | + height: 4rpx; | |
| 195 | + background: linear-gradient(90deg, #43a047 0%, #66bb6a 100%); | |
| 196 | + border-radius: 2rpx; | |
| 197 | + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
| 198 | + box-shadow: 0 2rpx 8rpx rgba(67, 160, 71, 0.4); | |
| 199 | + z-index: 1; | |
| 200 | + } | |
| 201 | + | |
| 148 | 202 | .list-item { |
| 149 | 203 | flex: 1; |
| 204 | + position: relative; | |
| 205 | + z-index: 2; | |
| 206 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| 207 | + | |
| 150 | 208 | .item-img-box { |
| 151 | 209 | width: 40rpx; |
| 152 | 210 | height: 40rpx; |
| 153 | 211 | margin-bottom: 6rpx; |
| 154 | 212 | position: relative; |
| 213 | + transition: transform 0.3s ease; | |
| 155 | 214 | } |
| 156 | 215 | |
| 157 | 216 | .item-img { |
| 158 | 217 | width: 40rpx; |
| 159 | 218 | height: 40rpx; |
| 219 | + transition: transform 0.3s ease; | |
| 220 | + } | |
| 221 | + | |
| 222 | + /* 3D悬浮动效 */ | |
| 223 | + &:active { | |
| 224 | + transform: translateY(-2rpx) scale(0.95); | |
| 225 | + | |
| 226 | + .item-img-box { | |
| 227 | + transform: scale(1.1); | |
| 228 | + } | |
| 160 | 229 | } |
| 161 | 230 | } |
| 162 | 231 | ... | ... |
绿纤uni-app/pages/me/me.vue
| ... | ... | @@ -691,14 +691,40 @@ export default { |
| 691 | 691 | } |
| 692 | 692 | |
| 693 | 693 | .warpboxss { |
| 694 | - background-color: rgba(255, 255, 255, 0.4); | |
| 695 | - backdrop-filter: blur(16px) saturate(180%); | |
| 696 | - -webkit-backdrop-filter: blur(16px) saturate(180%); | |
| 694 | + background: rgba(255, 255, 255, 0.25); | |
| 695 | + backdrop-filter: blur(20px) saturate(180%); | |
| 696 | + -webkit-backdrop-filter: blur(20px) saturate(180%); | |
| 697 | 697 | padding: 30rpx; |
| 698 | 698 | border-radius: 24rpx; |
| 699 | - box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08); | |
| 700 | - border: 1px solid rgba(255, 255, 255, 0.125); | |
| 699 | + box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.3) inset; | |
| 700 | + border: 1px solid rgba(255, 255, 255, 0.4); | |
| 701 | 701 | margin-bottom: 24rpx; |
| 702 | + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
| 703 | + transform: translateY(0) scale(1); | |
| 704 | + position: relative; | |
| 705 | + overflow: hidden; | |
| 706 | +} | |
| 707 | + | |
| 708 | +/* 3D悬浮动效 - 所有卡片 */ | |
| 709 | +.warpboxss::before { | |
| 710 | + content: ''; | |
| 711 | + position: absolute; | |
| 712 | + top: 0; | |
| 713 | + left: -100%; | |
| 714 | + width: 100%; | |
| 715 | + height: 100%; | |
| 716 | + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); | |
| 717 | + transition: left 0.6s ease; | |
| 718 | +} | |
| 719 | + | |
| 720 | +.warpboxss:active { | |
| 721 | + transform: translateY(-4rpx) scale(0.98); | |
| 722 | + box-shadow: 0 12rpx 48rpx rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.4) inset; | |
| 723 | + border-color: rgba(255, 255, 255, 0.5); | |
| 724 | +} | |
| 725 | + | |
| 726 | +.warpboxss:active::before { | |
| 727 | + left: 100%; | |
| 702 | 728 | } |
| 703 | 729 | |
| 704 | 730 | .warpboxs-small-title { |
| ... | ... | @@ -847,12 +873,17 @@ export default { |
| 847 | 873 | } |
| 848 | 874 | |
| 849 | 875 | .kpi-card { |
| 850 | - background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%); | |
| 876 | + background: linear-gradient(135deg, rgba(76, 175, 80, 0.85) 0%, rgba(102, 187, 106, 0.85) 100%); | |
| 877 | + backdrop-filter: blur(20px) saturate(180%); | |
| 878 | + -webkit-backdrop-filter: blur(20px) saturate(180%); | |
| 851 | 879 | border-radius: 24rpx; |
| 852 | 880 | padding: 40rpx 30rpx; |
| 853 | - box-shadow: 0 8rpx 24rpx rgba(76, 175, 80, 0.3); | |
| 881 | + box-shadow: 0 8rpx 32rpx rgba(76, 175, 80, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.2) inset; | |
| 882 | + border: 1px solid rgba(255, 255, 255, 0.3); | |
| 854 | 883 | position: relative; |
| 855 | 884 | overflow: hidden; |
| 885 | + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
| 886 | + transform: translateY(0) scale(1); | |
| 856 | 887 | |
| 857 | 888 | &::before { |
| 858 | 889 | content: ''; |
| ... | ... | @@ -861,13 +892,25 @@ export default { |
| 861 | 892 | right: -50%; |
| 862 | 893 | width: 200%; |
| 863 | 894 | height: 200%; |
| 864 | - background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%); | |
| 895 | + background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%); | |
| 896 | + transition: transform 0.6s ease; | |
| 897 | + } | |
| 898 | + | |
| 899 | + &:active { | |
| 900 | + transform: translateY(-6rpx) scale(0.97); | |
| 901 | + box-shadow: 0 16rpx 48rpx rgba(76, 175, 80, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.3) inset; | |
| 902 | + } | |
| 903 | + | |
| 904 | + &:active::before { | |
| 905 | + transform: rotate(180deg); | |
| 865 | 906 | } |
| 866 | 907 | |
| 867 | 908 | .kpi-title { |
| 868 | 909 | font-size: 26rpx; |
| 869 | - color: rgba(255, 255, 255, 0.9); | |
| 910 | + color: rgba(255, 255, 255, 0.95); | |
| 870 | 911 | margin-bottom: 16rpx; |
| 912 | + position: relative; | |
| 913 | + z-index: 1; | |
| 871 | 914 | } |
| 872 | 915 | |
| 873 | 916 | .kpi-value { |
| ... | ... | @@ -875,6 +918,8 @@ export default { |
| 875 | 918 | font-weight: 700; |
| 876 | 919 | color: #ffffff; |
| 877 | 920 | line-height: 1.2; |
| 921 | + position: relative; | |
| 922 | + z-index: 1; | |
| 878 | 923 | } |
| 879 | 924 | } |
| 880 | 925 | |
| ... | ... | @@ -895,6 +940,13 @@ export default { |
| 895 | 940 | flex-direction: column; |
| 896 | 941 | align-items: center; |
| 897 | 942 | text-align: center; |
| 943 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| 944 | + transform: translateY(0) scale(1); | |
| 945 | + cursor: pointer; | |
| 946 | + } | |
| 947 | + | |
| 948 | + .small-stat-item:active { | |
| 949 | + transform: translateY(-4rpx) scale(0.95); | |
| 898 | 950 | } |
| 899 | 951 | |
| 900 | 952 | .small-stat-icon { |
| ... | ... | @@ -951,13 +1003,38 @@ export default { |
| 951 | 1003 | } |
| 952 | 1004 | |
| 953 | 1005 | .data-card { |
| 954 | - background-color: rgba(255, 255, 255, 0.4); | |
| 955 | - backdrop-filter: blur(16px) saturate(180%); | |
| 956 | - -webkit-backdrop-filter: blur(16px) saturate(180%); | |
| 1006 | + background: rgba(255, 255, 255, 0.25); | |
| 1007 | + backdrop-filter: blur(20px) saturate(180%); | |
| 1008 | + -webkit-backdrop-filter: blur(20px) saturate(180%); | |
| 957 | 1009 | border-radius: 24rpx; |
| 958 | 1010 | padding: 30rpx; |
| 959 | - box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08); | |
| 960 | - border: 1px solid rgba(255, 255, 255, 0.125); | |
| 1011 | + box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.3) inset; | |
| 1012 | + border: 1px solid rgba(255, 255, 255, 0.4); | |
| 1013 | + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
| 1014 | + transform: translateY(0) scale(1); | |
| 1015 | + position: relative; | |
| 1016 | + overflow: hidden; | |
| 1017 | +} | |
| 1018 | + | |
| 1019 | +.data-card::before { | |
| 1020 | + content: ''; | |
| 1021 | + position: absolute; | |
| 1022 | + top: 0; | |
| 1023 | + left: -100%; | |
| 1024 | + width: 100%; | |
| 1025 | + height: 100%; | |
| 1026 | + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); | |
| 1027 | + transition: left 0.6s ease; | |
| 1028 | +} | |
| 1029 | + | |
| 1030 | +.data-card:active { | |
| 1031 | + transform: translateY(-4rpx) scale(0.98); | |
| 1032 | + box-shadow: 0 12rpx 48rpx rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.4) inset; | |
| 1033 | + border-color: rgba(255, 255, 255, 0.5); | |
| 1034 | +} | |
| 1035 | + | |
| 1036 | +.data-card:active::before { | |
| 1037 | + left: 100%; | |
| 961 | 1038 | } |
| 962 | 1039 | |
| 963 | 1040 | .data-card-title { | ... | ... |