feat(timer): 循环训练组进度改为圆环分段弧 + 信息气泡三行合一

- progress-ring 新增 sets/currentSet/resting/successColor 属性,
  圆环外圈绘制分段弧(已完成=主色/当前=呼吸光点/休息下一组=绿),单组模式零渲染
- timer 删除顶部 circuit-bar 进度面板,布局骨架三模式统一
- 呼吸环淡化(描边 0.55→0.20,柔光渐变强度减半)
- 目标卡与提示气泡合并为 info-bubble,状态文案(撑住/休息中/已暂停)并入气泡顶部
This commit is contained in:
2026-08-12 09:39:41 +08:00
parent 0464eeaba6
commit 05c4763e49
18 changed files with 720 additions and 497 deletions
+1 -49
View File
@@ -19,18 +19,11 @@ Page({
// 空则回退占位(人形图标 + "运动达人"),settings 改完回首页即刷新。
nickName: '',
avatarUrl: '',
// Ring number font size in rpx. WeChat auto-scales text by the user's
// font-size setting (fontSizeScaleFactor) but does NOT scale rpx box
// dimensions — so on a real device with enlarged system font the 84rpx
// number grows past the fixed-size circular ring and gets clipped. We
// cancel that scale here so the number renders at a constant visual size
// (matching the devtools/simulator) on every device. See _readFontScale().
targetTimeFontSize: 96,
streakCount: 0,
planName: '',
planDay: 1,
planTotal: 7,
// hero / 进度地图 / dial 相关展示字段(由 refresh 生成)
// hero / 进度地图 / 时长展示相关字段(由 refresh 生成)
greetText: '你好',
streakText: '今天开启坚持之旅',
questNodes: [],
@@ -52,50 +45,9 @@ Page({
onLoad() {
themeMod.applyThemeToPage(this)
this._readFontScale()
this._firstShow = true
},
/**
* Read the device's WeChat font-size scale and compensate the ring number
* so it never overflows the fixed circular clip on real devices.
*
* WeChat auto-applies `fontSizeScaleFactor` to ALL text (including rpx font
* sizes) but leaves rpx box dimensions untouched. A user who bumps up the
* system font therefore sees enlarged text inside a non-enlarged ring.
*
* CRITICAL asymmetry: the DevTools simulator reports the SAME
* `fontSizeScaleFactor` as a real device (the user's actual WeChat setting)
* but does NOT actually scale rendered text. So if we compensate there, the
* number ends up too small in the simulator. We therefore SKIP the
* compensation under DevTools (host.env === 'devtools') and keep the design
* size — matching what the simulator renders literally.
*
* On real devices, dividing our design size by the factor cancels the
* auto-scale, keeping the number a constant 96rpx-equivalent everywhere.
* Bounded so a bad reading can only ever make the number smaller (safe),
* never larger (overflow).
*/
_readFontScale() {
let factor = 1
try {
const info = wx.getAppBaseInfo ? wx.getAppBaseInfo() : wx.getSystemInfoSync()
const isDevtools = info.host && info.host.env === 'devtools'
if (!isDevtools) {
if (typeof info.fontSizeScaleFactor === 'number' && info.fontSizeScaleFactor > 0) {
factor = info.fontSizeScaleFactor
} else if (typeof info.fontSizeSetting === 'number' && info.fontSizeSetting > 0) {
// fontSizeScaleFactor == currentFontSize / standardFontSize(17px)
factor = info.fontSizeSetting / 17
}
}
} catch (e) {}
const DESIGN = 96
let size = Math.round(DESIGN / factor)
size = Math.max(48, Math.min(96, size))
this.setData({ targetTimeFontSize: size })
},
onShow() {
themeMod.applyThemeToPage(this)
try {