Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Hooke
/
lls_program
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
hookehuyr
2025-09-04 21:05:41 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
f5f9484b4370f115a0f3d23c41fcee9abcdf3bd8
f5f9484b
1 parent
9f66abff
feat(组件): 添加动态字体大小调整功能
为积分显示组件添加根据数字长度自动调整字体大小的功能,确保长数字的可读性
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
51 additions
and
13 deletions
src/components/PointsCollector.vue
src/components/TotalPointsDisplay.vue
src/components/PointsCollector.vue
View file @
f5f9484
...
...
@@ -4,7 +4,7 @@
<view class="center-circle">
<view class="total-points" @tap="handleGoToRewards">
<text v-if="!isOwner" class="family-points-label">家庭总积分</text>
<text class="points-number">{{ animatedTotalPoints }}分</text>
<text class="points-number"
:style="{ fontSize: dynamicFontSize }"
>{{ animatedTotalPoints }}分</text>
<text v-if="isOwner" class="points-label">去兑换</text>
</view>
</view>
...
...
@@ -35,7 +35,7 @@
</template>
<script setup>
import { ref, onMounted, defineProps, defineExpose, defineEmits, watch } from 'vue'
import { ref, onMounted, defineProps, defineExpose, defineEmits, watch
, computed
} from 'vue'
import Taro, { useDidShow } from '@tarojs/taro'
import { collectPointAPI } from '@/api/points'
...
...
@@ -68,6 +68,25 @@ const animatedTotalPoints = ref(props.totalPoints) // 动画中的总积分
const floatingItems = ref([]) // 漂浮的积分项
const isCollecting = ref(false) // 是否正在收集,防止重复触发
/**
* 根据数值长度动态计算字体大小
*/
const dynamicFontSize = computed(() => {
const pointsStr = animatedTotalPoints.value + '分'
const length = pointsStr.length
// 基础字体大小36rpx,超过6位数开始缩小
if (length <= 6) {
return '36rpx'
} else if (length <= 8) {
return '32rpx'
} else if (length <= 10) {
return '28rpx'
} else {
return '24rpx'
}
})
// source_type 中英文映射
const sourceTypeMap = {
'WALKING': '步数积分',
...
...
@@ -111,20 +130,20 @@ const generatePointsData = () => {
// 计算项目大小和半径
const sizeRatio = item.points / maxValue;
const size = baseSize + (sizeRatio * 40); // rpx
// 优化半径计算,确保在不同屏幕尺寸下都能正确计算边界
// 将rpx转换为百分比,考虑屏幕宽度和高度的比例
const sizeInVw = (size / 750) * 100; // 转换为vw单位的百分比
const aspectRatio = windowWidth / windowHeight;
const radiusPercent = (sizeInVw / 2) / aspectRatio; // 转换为高度百分比的半径
// 定义更严格的安全区域,确保积分不会跑出屏幕
const safeMargin = Math.max(radiusPercent * 1.2, 8); // 至少8%的安全边距
const minX = safeMargin;
const maxX = 100 - safeMargin;
const minY = safeMargin + 5; // 顶部额外5%边距
const maxY = Math.min(60, 100 - safeMargin); // 限制在视图的顶部60%或安全区域内
// 确保安全区域有效
if (minX >= maxX || minY >= maxY) {
console.warn('安全区域过小,使用默认位置');
...
...
@@ -147,7 +166,7 @@ const generatePointsData = () => {
// 在计算出的边界内生成位置
x = Math.random() * (maxX - minX) + minX;
y = Math.random() * (maxY - minY) + minY;
// 二次检查边界,确保不会超出屏幕
x = Math.max(safeMargin, Math.min(100 - safeMargin, x));
y = Math.max(safeMargin, Math.min(maxY, y));
...
...
@@ -189,16 +208,16 @@ const getItemStyle = (item) => {
const maxValue = Math.max(...(floatingItems.value.map(i => i.points).length > 0 ? floatingItems.value.map(i => i.points) : [1]));
const sizeRatio = item.points / maxValue;
const size = baseSize + (sizeRatio * 50); // 增大最大额外尺寸从40到50
// 计算动态字体大小
const baseFontSize = 20; // 基础字体大小 rpx
const maxFontSize = 24; // 最大字体大小 rpx
const minFontSize = 18; // 最小字体大小 rpx,提高最小值确保可读性
// 根据圆圈大小和文字长度计算合适的字体大小
const labelLength = item.sourceLabel?.length || 0;
const pointsLength = (item.points + '分').length;
// 优化字体计算:根据圆圈大小和文字长度动态调整
let dynamicFontSize = Math.max(
minFontSize,
...
...
@@ -207,12 +226,12 @@ const getItemStyle = (item) => {
baseFontSize * (size / 100) * (8 / Math.max(8, labelLength)) // 根据文字长度调整
)
);
// 确保长文字能在一行显示
if (labelLength > 4) {
dynamicFontSize = Math.max(minFontSize, dynamicFontSize * (4 / labelLength));
}
// 确保字体大小为整数
dynamicFontSize = Math.round(dynamicFontSize);
...
...
src/components/TotalPointsDisplay.vue
View file @
f5f9484
...
...
@@ -4,7 +4,7 @@
<view class="center-circle1">
<view class="total-points" @tap="handleGoToRewards">
<text v-if="!isOwner" class="family-points-label">家庭总积分</text>
<text class="points-number">{{ animatedTotalPoints }}分</text>
<text class="points-number"
:style="{ fontSize: dynamicFontSize }"
>{{ animatedTotalPoints }}分</text>
<text v-if="isOwner" class="points-label">去兑换</text>
</view>
</view>
...
...
@@ -12,7 +12,7 @@
</template>
<script setup>
import { ref, watch, onMounted, defineProps } from 'vue'
import { ref, watch, onMounted, defineProps
, computed
} from 'vue'
import Taro from '@tarojs/taro'
// 定义props
...
...
@@ -36,6 +36,25 @@ const props = defineProps({
const animatedTotalPoints = ref(0)
/**
* 根据数值长度动态计算字体大小
*/
const dynamicFontSize = computed(() => {
const pointsStr = animatedTotalPoints.value + '分'
const length = pointsStr.length
// 基础字体大小36rpx,超过6位数开始缩小
if (length <= 6) {
return '36rpx'
} else if (length <= 8) {
return '32rpx'
} else if (length <= 10) {
return '28rpx'
} else {
return '24rpx'
}
})
/**
* 数字滚动动画
* @param {number} start - 动画开始值
* @param {number} end - 动画结束值
...
...
Please
register
or
login
to post a comment