feat(弹幕组件): 添加原生弹幕组件并集成到排行榜页面
- 新增 NativeDanmuComponent 原生弹幕组件,支持多轨道弹幕展示 - 在家庭排行榜页面集成弹幕功能,展示助力榜内容 - 调整排行榜卡片布局和样式,优化助力码按钮位置 - 添加弹幕点击和悬停事件处理逻辑
Showing
4 changed files
with
79 additions
and
15 deletions
| ... | @@ -13,6 +13,7 @@ declare module 'vue' { | ... | @@ -13,6 +13,7 @@ declare module 'vue' { |
| 13 | BottomNav: typeof import('./src/components/BottomNav.vue')['default'] | 13 | BottomNav: typeof import('./src/components/BottomNav.vue')['default'] |
| 14 | FamilyAlbum: typeof import('./src/components/FamilyAlbum.vue')['default'] | 14 | FamilyAlbum: typeof import('./src/components/FamilyAlbum.vue')['default'] |
| 15 | GlassCard: typeof import('./src/components/GlassCard.vue')['default'] | 15 | GlassCard: typeof import('./src/components/GlassCard.vue')['default'] |
| 16 | + NativeDanmuComponent: typeof import('./src/components/NativeDanmuComponent.vue')['default'] | ||
| 16 | NavBar: typeof import('./src/components/navBar.vue')['default'] | 17 | NavBar: typeof import('./src/components/navBar.vue')['default'] |
| 17 | NumberRoll: typeof import('./src/components/NumberRoll.vue')['default'] | 18 | NumberRoll: typeof import('./src/components/NumberRoll.vue')['default'] |
| 18 | NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet'] | 19 | NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet'] | ... | ... |
src/components/NativeDanmuComponent.vue
0 → 100644
This diff is collapsed. Click to expand it.
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-01-09 00:00:00 | 2 | * @Date: 2025-01-09 00:00:00 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-10-28 13:33:56 | 4 | + * @LastEditTime: 2025-10-28 16:24:46 |
| 5 | * @FilePath: /lls_program/src/components/RankingCard.vue | 5 | * @FilePath: /lls_program/src/components/RankingCard.vue |
| 6 | * @Description: 排行榜卡片组件 | 6 | * @Description: 排行榜卡片组件 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <view class="ranking-card bg-blue-500 bg-opacity-50"> | 9 | <view class="ranking-card bg-blue-500 bg-opacity-50"> |
| 10 | <!-- 卡片头部 --> | 10 | <!-- 卡片头部 --> |
| 11 | - <view class="card-header"> | 11 | + <view class="card-header" style="margin: 40rpx;"> |
| 12 | <view class="card-title flex items-center"> | 12 | <view class="card-title flex items-center"> |
| 13 | <IconFont size="20" name="https://cdn.ipadbiz.cn/lls_prog/icon/%E5%A5%96%E6%9D%AF.png" /> | 13 | <IconFont size="20" name="https://cdn.ipadbiz.cn/lls_prog/icon/%E5%A5%96%E6%9D%AF.png" /> |
| 14 | <text class="ml-2">家庭步数总榜</text> | 14 | <text class="ml-2">家庭步数总榜</text> |
| ... | @@ -17,7 +17,7 @@ | ... | @@ -17,7 +17,7 @@ |
| 17 | </view> | 17 | </view> |
| 18 | 18 | ||
| 19 | <!-- 顶部导航 --> | 19 | <!-- 顶部导航 --> |
| 20 | - <view class="nav-tabs"> | 20 | + <view class="nav-tabs" style="margin: 40rpx;"> |
| 21 | <!-- 滑动指示器 --> | 21 | <!-- 滑动指示器 --> |
| 22 | <view | 22 | <view |
| 23 | class="tab-indicator" | 23 | class="tab-indicator" |
| ... | @@ -39,12 +39,12 @@ | ... | @@ -39,12 +39,12 @@ |
| 39 | </view> | 39 | </view> |
| 40 | 40 | ||
| 41 | <!-- 排行榜内容 --> | 41 | <!-- 排行榜内容 --> |
| 42 | - <view class="rank-content" :class="{ 'content-switching': isContentSwitching }"> | 42 | + <view class="rank-content" :class="{ 'content-switching': isContentSwitching }" style="margin: 40rpx;"> |
| 43 | <!-- 排行榜日期 --> | 43 | <!-- 排行榜日期 --> |
| 44 | <view class="rank-date relative"> | 44 | <view class="rank-date relative"> |
| 45 | <!-- <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text v-if="activeTab !== 'shanghai'" class="ml-2">排名</text><IconFont name="ask" size="16" class="ml-2" @click="handleRankAskClick"></IconFont></view> --> | 45 | <!-- <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text v-if="activeTab !== 'shanghai'" class="ml-2">排名</text><IconFont name="ask" size="16" class="ml-2" @click="handleRankAskClick"></IconFont></view> --> |
| 46 | <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text class="ml-2">排名</text><IconFont name="ask" size="16" class="ml-2" @click="handleRankAskClick"></IconFont></view> | 46 | <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text class="ml-2">排名</text><IconFont name="ask" size="16" class="ml-2" @click="handleRankAskClick"></IconFont></view> |
| 47 | - <view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 0rpx; top: 50rpx; font-size: 23rpx; z-index: 999;" @tap="joinOrganization">助力码</view> | 47 | + <view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: -30rpx; top: -5rpx; font-size: 23rpx; z-index: 999;" @tap="joinOrganization">助力码</view> |
| 48 | </view> | 48 | </view> |
| 49 | 49 | ||
| 50 | <!-- <view v-if="activeTab === 'shanghai'" class="relative mb-2 text-white"> | 50 | <!-- <view v-if="activeTab === 'shanghai'" class="relative mb-2 text-white"> |
| ... | @@ -124,9 +124,21 @@ | ... | @@ -124,9 +124,21 @@ |
| 124 | </view> | 124 | </view> |
| 125 | </view> | 125 | </view> |
| 126 | 126 | ||
| 127 | + <!-- 弹幕显示助力榜内容 --> | ||
| 128 | + <view v-if="activeTab === 'support'" class="danmu-section"> | ||
| 129 | + <NativeDanmuComponent | ||
| 130 | + :container-height="700" | ||
| 131 | + :show-controls="true" | ||
| 132 | + :track-count="3" | ||
| 133 | + @danmu-click="handleDanmuClick" | ||
| 134 | + @danmu-hover="handleDanmuHover" | ||
| 135 | + ref="danmuRef" | ||
| 136 | + /> | ||
| 137 | + </view> | ||
| 138 | + | ||
| 127 | <!-- 我的排名卡片 --> | 139 | <!-- 我的排名卡片 --> |
| 128 | <!-- 特殊写法 因为直接写一个排名卡片排名数字有被截断问题 --> | 140 | <!-- 特殊写法 因为直接写一个排名卡片排名数字有被截断问题 --> |
| 129 | - <view v-if="myRank && topRanks.length > 0 && activeTab !== 'support'" class="my-rank-section"> | 141 | + <view v-if="myRank && topRanks.length > 0 && activeTab !== 'support'" class="my-rank-section" style="margin: 40rpx;"> |
| 130 | <view class="my-rank-content"> | 142 | <view class="my-rank-content"> |
| 131 | <view class="my-rank-left"> | 143 | <view class="my-rank-left"> |
| 132 | <view class="my-rank-number"> | 144 | <view class="my-rank-number"> |
| ... | @@ -145,7 +157,7 @@ | ... | @@ -145,7 +157,7 @@ |
| 145 | </view> | 157 | </view> |
| 146 | </view> | 158 | </view> |
| 147 | </view> | 159 | </view> |
| 148 | - <view v-if="myRank && !topRanks.length && activeTab !== 'support'" class="my-rank-section"> | 160 | + <view v-if="myRank && !topRanks.length && activeTab !== 'support'" class="my-rank-section" style="margin: 40rpx;"> |
| 149 | <view class="my-rank-content"> | 161 | <view class="my-rank-content"> |
| 150 | <view class="my-rank-left"> | 162 | <view class="my-rank-left"> |
| 151 | <view class="my-rank-number"> | 163 | <view class="my-rank-number"> |
| ... | @@ -192,7 +204,8 @@ | ... | @@ -192,7 +204,8 @@ |
| 192 | import { ref, computed, onMounted, watch, nextTick } from 'vue' | 204 | import { ref, computed, onMounted, watch, nextTick } from 'vue' |
| 193 | import Taro from '@tarojs/taro' | 205 | import Taro from '@tarojs/taro' |
| 194 | import { IconFont } from '@nutui/icons-vue-taro'; | 206 | import { IconFont } from '@nutui/icons-vue-taro'; |
| 195 | -import NumberRoll from './NumberRoll.vue' | 207 | +// import NumberRoll from './NumberRoll.vue' |
| 208 | +import NativeDanmuComponent from '@/components/NativeDanmuComponent.vue' | ||
| 196 | // 默认头像 | 209 | // 默认头像 |
| 197 | const defaultAvatar = 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60' | 210 | const defaultAvatar = 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60' |
| 198 | // 助力榜图片 | 211 | // 助力榜图片 |
| ... | @@ -510,6 +523,27 @@ const refreshData = async () => { | ... | @@ -510,6 +523,27 @@ const refreshData = async () => { |
| 510 | await loadLeaderboardData(true) | 523 | await loadLeaderboardData(true) |
| 511 | } | 524 | } |
| 512 | 525 | ||
| 526 | + | ||
| 527 | +/** | ||
| 528 | + * 弹幕组件相关 | ||
| 529 | + */ | ||
| 530 | +const danmuRef = ref(null) | ||
| 531 | + | ||
| 532 | +// 处理弹幕点击事件 | ||
| 533 | +const handleDanmuClick = (familyData) => { | ||
| 534 | + console.log('弹幕点击:', familyData) | ||
| 535 | + Taro.showToast({ | ||
| 536 | + title: `点击了${familyData.familyName}`, | ||
| 537 | + icon: 'none', | ||
| 538 | + duration: 2000 | ||
| 539 | + }) | ||
| 540 | +} | ||
| 541 | + | ||
| 542 | +// 处理弹幕悬停事件 | ||
| 543 | +const handleDanmuHover = (familyData) => { | ||
| 544 | + console.log('弹幕悬停:', familyData) | ||
| 545 | +} | ||
| 546 | + | ||
| 513 | /** | 547 | /** |
| 514 | * 页面初始化 | 548 | * 页面初始化 |
| 515 | */ | 549 | */ |
| ... | @@ -539,7 +573,7 @@ defineExpose({ | ... | @@ -539,7 +573,7 @@ defineExpose({ |
| 539 | // background: linear-gradient(180deg, var(--primary-color) 0%, var(--primary-color) 100%); | 573 | // background: linear-gradient(180deg, var(--primary-color) 0%, var(--primary-color) 100%); |
| 540 | // background: var(--primary-color); | 574 | // background: var(--primary-color); |
| 541 | border-radius: 20rpx; | 575 | border-radius: 20rpx; |
| 542 | - padding: 40rpx; | 576 | + // padding: 40rpx; |
| 543 | margin: 30rpx; | 577 | margin: 30rpx; |
| 544 | margin-bottom: 0; | 578 | margin-bottom: 0; |
| 545 | position: relative; | 579 | position: relative; | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-09-01 13:07:52 | 2 | * @Date: 2025-09-01 13:07:52 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-10-28 13:32:48 | 4 | + * @LastEditTime: 2025-10-28 16:04:30 |
| 5 | * @FilePath: /lls_program/src/pages/FamilyRank/index.vue | 5 | * @FilePath: /lls_program/src/pages/FamilyRank/index.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -42,7 +42,7 @@ | ... | @@ -42,7 +42,7 @@ |
| 42 | <view v-if="!loading" class="rank-date relative"> | 42 | <view v-if="!loading" class="rank-date relative"> |
| 43 | <!-- <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text v-if="activeTab !== 'shanghai'" class="ml-2">排名</text><IconFont name="ask" size="14" class="ml-2" @click="handleRankAskClick"></IconFont></view> --> | 43 | <!-- <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text v-if="activeTab !== 'shanghai'" class="ml-2">排名</text><IconFont name="ask" size="14" class="ml-2" @click="handleRankAskClick"></IconFont></view> --> |
| 44 | <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text class="ml-2">排名</text><IconFont name="ask" size="14" class="ml-2" @click="handleRankAskClick"></IconFont></view> | 44 | <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text class="ml-2">排名</text><IconFont name="ask" size="14" class="ml-2" @click="handleRankAskClick"></IconFont></view> |
| 45 | - <view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 40rpx; top: 50rpx; font-size: 23rpx;" @tap="joinOrganization">助力码</view> | 45 | + <view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 45rpx; top: -5rpx; font-size: 23rpx;" @tap="joinOrganization">助力码</view> |
| 46 | </view> | 46 | </view> |
| 47 | 47 | ||
| 48 | <!-- 参与家庭数量显示 --> | 48 | <!-- 参与家庭数量显示 --> |
| ... | @@ -154,7 +154,18 @@ | ... | @@ -154,7 +154,18 @@ |
| 154 | <view class="no-data-text">暂无助力排行榜更多数据</view> | 154 | <view class="no-data-text">暂无助力排行榜更多数据</view> |
| 155 | </view> --> | 155 | </view> --> |
| 156 | 156 | ||
| 157 | - <!-- 弹幕显示助力榜内容 --> | 157 | + </view> |
| 158 | + | ||
| 159 | + <!-- 弹幕显示助力榜内容 --> | ||
| 160 | + <view v-if="activeTab === 'support'" class="danmu-section mt-8"> | ||
| 161 | + <NativeDanmuComponent | ||
| 162 | + :container-height="1200" | ||
| 163 | + :show-controls="true" | ||
| 164 | + :track-count="7" | ||
| 165 | + @danmu-click="handleDanmuClick" | ||
| 166 | + @danmu-hover="handleDanmuHover" | ||
| 167 | + ref="danmuRef" | ||
| 168 | + /> | ||
| 158 | </view> | 169 | </view> |
| 159 | 170 | ||
| 160 | <!-- 我的排名悬浮卡片 --> | 171 | <!-- 我的排名悬浮卡片 --> |
| ... | @@ -209,8 +220,8 @@ import { ref, computed, onMounted } from 'vue' | ... | @@ -209,8 +220,8 @@ import { ref, computed, onMounted } from 'vue' |
| 209 | import Taro from '@tarojs/taro' | 220 | import Taro from '@tarojs/taro' |
| 210 | import { IconFont } from '@nutui/icons-vue-taro'; | 221 | import { IconFont } from '@nutui/icons-vue-taro'; |
| 211 | import BackToTop from '@/components/BackToTop.vue' | 222 | import BackToTop from '@/components/BackToTop.vue' |
| 223 | +import NativeDanmuComponent from '@/components/NativeDanmuComponent.vue' | ||
| 212 | // import NumberRoll from '@/components/NumberRoll.vue' | 224 | // import NumberRoll from '@/components/NumberRoll.vue' |
| 213 | -import vueDanmaku from 'vue-danmaku' | ||
| 214 | // 默认头像 | 225 | // 默认头像 |
| 215 | const defaultAvatar = 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60' | 226 | const defaultAvatar = 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60' |
| 216 | const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png' | 227 | const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png' |
| ... | @@ -268,6 +279,26 @@ const handleRankAskClick = () => { | ... | @@ -268,6 +279,26 @@ const handleRankAskClick = () => { |
| 268 | } | 279 | } |
| 269 | 280 | ||
| 270 | /** | 281 | /** |
| 282 | + * 弹幕组件相关 | ||
| 283 | + */ | ||
| 284 | +const danmuRef = ref(null) | ||
| 285 | + | ||
| 286 | +// 处理弹幕点击事件 | ||
| 287 | +const handleDanmuClick = (familyData) => { | ||
| 288 | + console.log('弹幕点击:', familyData) | ||
| 289 | + Taro.showToast({ | ||
| 290 | + title: `点击了${familyData.familyName}`, | ||
| 291 | + icon: 'none', | ||
| 292 | + duration: 2000 | ||
| 293 | + }) | ||
| 294 | +} | ||
| 295 | + | ||
| 296 | +// 处理弹幕悬停事件 | ||
| 297 | +const handleDanmuHover = (familyData) => { | ||
| 298 | + console.log('弹幕悬停:', familyData) | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | +/** | ||
| 271 | * 触发数字滚动动画 | 302 | * 触发数字滚动动画 |
| 272 | */ | 303 | */ |
| 273 | const triggerNumberRoll = () => { | 304 | const triggerNumberRoll = () => { |
| ... | @@ -1039,7 +1070,5 @@ onMounted(async () => { | ... | @@ -1039,7 +1070,5 @@ onMounted(async () => { |
| 1039 | } | 1070 | } |
| 1040 | } | 1071 | } |
| 1041 | } | 1072 | } |
| 1042 | - | ||
| 1043 | - | ||
| 1044 | } | 1073 | } |
| 1045 | </style> | 1074 | </style> | ... | ... |
-
Please register or login to post a comment