hookehuyr

feat(动画): 优化数字滚动动画触发逻辑

添加状态锁防止数字滚动动画重复触发
将动画触发逻辑从数据加载函数移到切换函数中
添加数据重新加载时的动画触发逻辑
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-25 19:35:03 4 + * @LastEditTime: 2025-10-25 19:47:47
5 * @FilePath: /lls_program/src/components/RankingCard.vue 5 * @FilePath: /lls_program/src/components/RankingCard.vue
6 * @Description: 排行榜卡片组件 6 * @Description: 排行榜卡片组件
7 --> 7 -->
...@@ -289,6 +289,16 @@ const switchTab = async (tab) => { ...@@ -289,6 +289,16 @@ const switchTab = async (tab) => {
289 // 重新加载排行榜数据 289 // 重新加载排行榜数据
290 await loadLeaderboardData(false) 290 await loadLeaderboardData(false)
291 291
292 + // 数据加载完成后触发数字滚动动画
293 + setTimeout(() => {
294 + // 先重置数字滚动状态
295 + resetNumberRoll()
296 + // 延迟一点再触发滚动
297 + setTimeout(() => {
298 + triggerNumberRoll()
299 + }, 100)
300 + }, 300)
301 +
292 // 内容切换后,结束切换状态,开始淡入动画 302 // 内容切换后,结束切换状态,开始淡入动画
293 setTimeout(() => { 303 setTimeout(() => {
294 isContentSwitching.value = false 304 isContentSwitching.value = false
...@@ -325,14 +335,6 @@ const loadLeaderboardData = async (isInitialLoad = false) => { ...@@ -325,14 +335,6 @@ const loadLeaderboardData = async (isInitialLoad = false) => {
325 currentDate.value = response.data.yesterday 335 currentDate.value = response.data.yesterday
326 // TODO: 设置总家庭数 336 // TODO: 设置总家庭数
327 currentTotalFamilySum.value = 2318; 337 currentTotalFamilySum.value = 2318;
328 -
329 - // 数据加载完成后,延迟触发数字滚动动画
330 - setTimeout(() => {
331 - resetNumberRoll()
332 - setTimeout(() => {
333 - triggerNumberRoll()
334 - }, 100)
335 - }, 300)
336 } 338 }
337 } catch (error) { 339 } catch (error) {
338 console.error('获取排行榜数据失败:', error) 340 console.error('获取排行榜数据失败:', error)
......
...@@ -295,6 +295,13 @@ const handleStepsSynced = async () => { ...@@ -295,6 +295,13 @@ const handleStepsSynced = async () => {
295 console.log('微信步数同步完成,开始刷新Dashboard页面数据') 295 console.log('微信步数同步完成,开始刷新Dashboard页面数据')
296 // 步数同步完成后,调用统一的数据刷新函数 296 // 步数同步完成后,调用统一的数据刷新函数
297 await refreshDashboardData(); 297 await refreshDashboardData();
298 +
299 + // 如果已经触发过页面滚动,则在数据刷新后触发数字滚动
300 + if (hasTriggeredNumberRoll.value) {
301 + setTimeout(() => {
302 + triggerNumberRollForDataReload();
303 + }, 500);
304 + }
298 } 305 }
299 306
300 /** 307 /**
...@@ -307,6 +314,8 @@ const handleSyncFailed = (data) => { ...@@ -307,6 +314,8 @@ const handleSyncFailed = (data) => {
307 314
308 // 滚动监听相关 315 // 滚动监听相关
309 const hasTriggeredNumberRoll = ref(false) 316 const hasTriggeredNumberRoll = ref(false)
317 +// 防止重复触发的状态锁
318 +const isNumberRollInProgress = ref(false)
310 319
311 // 监听全局的微信步数同步成功事件(用于处理401重试后的成功情况) 320 // 监听全局的微信步数同步成功事件(用于处理401重试后的成功情况)
312 onMounted(() => { 321 onMounted(() => {
...@@ -508,6 +517,13 @@ useDidShow(async () => { ...@@ -508,6 +517,13 @@ useDidShow(async () => {
508 if (familyAlbumRef.value) { 517 if (familyAlbumRef.value) {
509 familyAlbumRef.value.refreshData(); 518 familyAlbumRef.value.refreshData();
510 } 519 }
520 +
521 + // 如果已经触发过页面滚动,则在数据刷新后触发数字滚动
522 + if (hasTriggeredNumberRoll.value) {
523 + setTimeout(() => {
524 + triggerNumberRollForDataReload();
525 + }, 500);
526 + }
511 }) 527 })
512 528
513 useReady(async () => { 529 useReady(async () => {
...@@ -670,17 +686,50 @@ const handlePageScroll = (scrollTop) => { ...@@ -670,17 +686,50 @@ const handlePageScroll = (scrollTop) => {
670 * 触发数字滚动动画 686 * 触发数字滚动动画
671 */ 687 */
672 const triggerNumberRoll = () => { 688 const triggerNumberRoll = () => {
673 - if (hasTriggeredNumberRoll.value) { 689 + if (hasTriggeredNumberRoll.value || isNumberRollInProgress.value) {
674 return 690 return
675 } 691 }
676 692
677 hasTriggeredNumberRoll.value = true 693 hasTriggeredNumberRoll.value = true
694 + isNumberRollInProgress.value = true
678 695
679 // 延迟一点时间再触发,让用户看到滚动效果 696 // 延迟一点时间再触发,让用户看到滚动效果
680 setTimeout(() => { 697 setTimeout(() => {
681 if (rankingCardRef.value && rankingCardRef.value.startNumberRoll) { 698 if (rankingCardRef.value && rankingCardRef.value.startNumberRoll) {
682 rankingCardRef.value.startNumberRoll() 699 rankingCardRef.value.startNumberRoll()
683 } 700 }
701 + // 滚动完成后重置状态锁
702 + setTimeout(() => {
703 + isNumberRollInProgress.value = false
704 + }, 1000) // 假设滚动动画需要1秒
705 + }, 300)
706 +}
707 +
708 +/**
709 + * 触发数字滚动动画(用于数据重新加载时)
710 + */
711 +const triggerNumberRollForDataReload = () => {
712 + // 如果正在进行滚动动画,则跳过
713 + if (isNumberRollInProgress.value) {
714 + return
715 + }
716 +
717 + isNumberRollInProgress.value = true
718 +
719 + // 重置状态,允许重新触发
720 + if (rankingCardRef.value && rankingCardRef.value.resetNumberRoll) {
721 + rankingCardRef.value.resetNumberRoll()
722 + }
723 +
724 + // 延迟一点时间再触发,让用户看到滚动效果
725 + setTimeout(() => {
726 + if (rankingCardRef.value && rankingCardRef.value.startNumberRoll) {
727 + rankingCardRef.value.startNumberRoll()
728 + }
729 + // 滚动完成后重置状态锁
730 + setTimeout(() => {
731 + isNumberRollInProgress.value = false
732 + }, 1000) // 假设滚动动画需要1秒
684 }, 300) 733 }, 300)
685 } 734 }
686 </script> 735 </script>
......