优化勋章分段进度展示

This commit is contained in:
2026-07-29 11:45:20 +08:00
parent 11d49a26df
commit 903951aee0
5 changed files with 109 additions and 20 deletions
+46 -3
View File
@@ -1,5 +1,15 @@
const TRACK_PAD = 4
const roundPosition = (value) => Math.round(value * 10) / 10
const getBadgePositions = (badges) => {
const defs = Array.isArray(badges) ? badges : []
if (defs.length === 0) return []
if (defs.length === 1) return [TRACK_PAD]
const segmentWidth = (100 - TRACK_PAD * 2) / (defs.length - 1)
return defs.map((_, index) => roundPosition(TRACK_PAD + index * segmentWidth))
}
const getBadgeProgress = (badges, totalDays) => {
const defs = Array.isArray(badges) ? badges : []
if (defs.length === 0) return 0
@@ -8,12 +18,39 @@ const getBadgeProgress = (badges, totalDays) => {
if (days < defs[0].days) return 0
if (defs.length === 1 || days >= defs[defs.length - 1].days) return 100
const segmentWidth = (100 - TRACK_PAD * 2) / (defs.length - 1)
const positions = getBadgePositions(defs)
let index = 0
while (index < defs.length - 1 && days >= defs[index + 1].days) index++
const ratio = (days - defs[index].days) / (defs[index + 1].days - defs[index].days)
return Math.round((TRACK_PAD + index * segmentWidth + ratio * segmentWidth) * 10) / 10
return roundPosition(positions[index] + ratio * (positions[index + 1] - positions[index]))
}
const getBadgeSegments = (badges, totalDays) => {
const defs = Array.isArray(badges) ? badges : []
const positions = getBadgePositions(defs)
const days = Math.max(0, Number(totalDays) || 0)
return defs.slice(0, -1).map((badge, index) => {
const nextBadge = defs[index + 1]
const segmentDays = nextBadge.days - badge.days
const progress = days <= badge.days
? 0
: days >= nextBadge.days
? 100
: roundPosition((days - badge.days) / segmentDays * 100)
return {
left: positions[index],
width: roundPosition(positions[index + 1] - positions[index]),
progress
}
})
}
const getBadgeDisplayLabel = (badge, unlocked) => {
if (!badge) return ''
return unlocked && badge.name ? badge.name : `${badge.days}`
}
const getBadgeCelebration = (previous, unlockedDays) => {
@@ -25,4 +62,10 @@ const getBadgeCelebration = (previous, unlockedDays) => {
return { newly, seen: Array.from(new Set(previous.concat(unlocked))) }
}
module.exports = { getBadgeProgress, getBadgeCelebration }
module.exports = {
getBadgeProgress,
getBadgePositions,
getBadgeSegments,
getBadgeDisplayLabel,
getBadgeCelebration
}