feat(打卡页面): 添加悬浮打卡按钮的紧凑模式
在页面滚动超过200px时,将悬浮打卡按钮切换为紧凑的圆形模式以节省空间
Showing
1 changed file
with
54 additions
and
4 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-05-29 15:34:17 | 2 | * @Date: 2025-05-29 15:34:17 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-12-18 14:43:10 | 4 | + * @LastEditTime: 2025-12-18 22:47:39 |
| 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -123,7 +123,7 @@ | ... | @@ -123,7 +123,7 @@ |
| 123 | <van-back-top right="5vw" bottom="25vh" offset="600" /> | 123 | <van-back-top right="5vw" bottom="25vh" offset="600" /> |
| 124 | 124 | ||
| 125 | <!-- 底部悬浮打卡按钮 --> | 125 | <!-- 底部悬浮打卡按钮 --> |
| 126 | - <div v-if="!taskDetail.is_finish" class="floating-checkin-button"> | 126 | + <div v-if="!taskDetail.is_finish" class="floating-checkin-button" :class="{ 'is-compact': isCompactButton }"> |
| 127 | <van-button | 127 | <van-button |
| 128 | type="primary" | 128 | type="primary" |
| 129 | round | 129 | round |
| ... | @@ -131,7 +131,7 @@ | ... | @@ -131,7 +131,7 @@ |
| 131 | class="checkin-action-button" | 131 | class="checkin-action-button" |
| 132 | > | 132 | > |
| 133 | <van-icon name="edit" size="1.2rem" /> | 133 | <van-icon name="edit" size="1.2rem" /> |
| 134 | - <span style="margin-left: 0.5rem;">我要打卡</span> | 134 | + <span class="button-text">我要打卡</span> |
| 135 | </van-button> | 135 | </van-button> |
| 136 | </div> | 136 | </div> |
| 137 | </AppLayout> | 137 | </AppLayout> |
| ... | @@ -146,7 +146,7 @@ import FrostedGlass from "@/components/ui/FrostedGlass.vue"; | ... | @@ -146,7 +146,7 @@ import FrostedGlass from "@/components/ui/FrostedGlass.vue"; |
| 146 | import CollapsibleCalendar from "@/components/ui/CollapsibleCalendar.vue"; | 146 | import CollapsibleCalendar from "@/components/ui/CollapsibleCalendar.vue"; |
| 147 | import PostCountModel from "@/components/count/postCountModel.vue"; | 147 | import PostCountModel from "@/components/count/postCountModel.vue"; |
| 148 | import CheckinCard from "@/components/checkin/CheckinCard.vue"; | 148 | import CheckinCard from "@/components/checkin/CheckinCard.vue"; |
| 149 | -import { useTitle, useResizeObserver } from '@vueuse/core'; | 149 | +import { useTitle, useResizeObserver, useScroll } from '@vueuse/core'; |
| 150 | import dayjs from 'dayjs'; | 150 | import dayjs from 'dayjs'; |
| 151 | 151 | ||
| 152 | import { getTaskDetailAPI, getUploadTaskListAPI, delUploadTaskInfoAPI, likeUploadTaskInfoAPI, dislikeUploadTaskInfoAPI } from "@/api/checkin"; | 152 | import { getTaskDetailAPI, getUploadTaskListAPI, delUploadTaskInfoAPI, likeUploadTaskInfoAPI, dislikeUploadTaskInfoAPI } from "@/api/checkin"; |
| ... | @@ -156,6 +156,10 @@ const route = useRoute() | ... | @@ -156,6 +156,10 @@ const route = useRoute() |
| 156 | const router = useRouter() | 156 | const router = useRouter() |
| 157 | useTitle(route.meta.title); | 157 | useTitle(route.meta.title); |
| 158 | 158 | ||
| 159 | +// 滚动监听 | ||
| 160 | +const { y } = useScroll(window) | ||
| 161 | +const isCompactButton = computed(() => y.value > 200) | ||
| 162 | + | ||
| 159 | // 动态字段文字 | 163 | // 动态字段文字 |
| 160 | const dynamicFieldText = ref('感恩') | 164 | const dynamicFieldText = ref('感恩') |
| 161 | 165 | ||
| ... | @@ -792,15 +796,61 @@ const formatData = (data) => { | ... | @@ -792,15 +796,61 @@ const formatData = (data) => { |
| 792 | right: 1rem; | 796 | right: 1rem; |
| 793 | z-index: 10; | 797 | z-index: 10; |
| 794 | padding: 0 1rem; | 798 | padding: 0 1rem; |
| 799 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
| 800 | + pointer-events: none; /* 允许点击穿透,只响应按钮点击 */ | ||
| 801 | + display: flex; | ||
| 802 | + justify-content: center; | ||
| 795 | } | 803 | } |
| 796 | 804 | ||
| 797 | .floating-checkin-button .checkin-action-button { | 805 | .floating-checkin-button .checkin-action-button { |
| 806 | + pointer-events: auto; | ||
| 798 | width: 100%; | 807 | width: 100%; |
| 799 | height: 3rem; | 808 | height: 3rem; |
| 800 | font-size: 1rem; | 809 | font-size: 1rem; |
| 801 | font-weight: 600; | 810 | font-weight: 600; |
| 802 | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); | 811 | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); |
| 803 | border: none; | 812 | border: none; |
| 813 | + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||
| 814 | + display: flex; | ||
| 815 | + align-items: center; | ||
| 816 | + justify-content: center; | ||
| 817 | +} | ||
| 818 | + | ||
| 819 | +.floating-checkin-button .button-text { | ||
| 820 | + margin-left: 0.5rem; | ||
| 821 | + transition: all 0.3s ease; | ||
| 822 | + max-width: 100px; | ||
| 823 | + opacity: 1; | ||
| 824 | + overflow: hidden; | ||
| 825 | + white-space: nowrap; | ||
| 826 | +} | ||
| 827 | + | ||
| 828 | +/* 紧凑模式(圆形按钮) */ | ||
| 829 | +.floating-checkin-button.is-compact { | ||
| 830 | + left: auto; | ||
| 831 | + right: 1.5rem; | ||
| 832 | + width: auto; | ||
| 833 | + padding: 0; | ||
| 834 | +} | ||
| 835 | + | ||
| 836 | +.floating-checkin-button.is-compact .checkin-action-button { | ||
| 837 | + width: 3.5rem; | ||
| 838 | + height: 3.5rem; | ||
| 839 | + border-radius: 50%; | ||
| 840 | + padding: 0; | ||
| 841 | +} | ||
| 842 | + | ||
| 843 | +/* 放大图标 */ | ||
| 844 | +.floating-checkin-button.is-compact .checkin-action-button :deep(.van-icon) { | ||
| 845 | + font-size: 1.5rem !important; | ||
| 846 | +} | ||
| 847 | + | ||
| 848 | +.floating-checkin-button.is-compact .button-text { | ||
| 849 | + max-width: 0; | ||
| 850 | + margin-left: 0; | ||
| 851 | + opacity: 0; | ||
| 852 | + /* 确保隐藏后完全不占位 */ | ||
| 853 | + display: none; | ||
| 804 | } | 854 | } |
| 805 | 855 | ||
| 806 | :deep(.van-calendar__footer) { | 856 | :deep(.van-calendar__footer) { | ... | ... |
-
Please register or login to post a comment