Files
fenix8v3-watchface/README.md
ericwyuan 22340b09fa 机型覆盖 17 → 55 款,补 LICENSE 与 CHANGELOG
机型
  新增 38 款圆屏 + CIQ ≥ 4.2 的机型:fenix 7 Pro 全系、Venu 2/3S、
  Approach S50/S70、Descent G2/Mk3、D2 系列、Instinct 3 AMOLED、
  FR255S/265S/570/955 等。其中 34 款的屏宽已有现成图标资源。

  机型列表和 monkey.jungle 改由 tools/gen_devices.py 扫描本机 SDK 生成,
  筛选条件是「支持 watchFace + 圆屏 + CIQ ≥ 4.2」(Complications 要 4.2)。
  55 条资源路径不再手写。

  新增 218px 与 360px 两档图标。218px 上图标只有 14×14,设计稿里太阳与云
  之间那道 1.7 设计像素的暗缝连一个物理像素都占不到,光栅化出来是一坨没有
  结构的橙块 —— 该尺寸改用按目标像素直接摆的简化标记。

常亮模式:结论是不改
  为了压所谓的 10% 点亮率,一度把进度环也砍掉了。换成平均亮度(AMOLED 功耗
  的合理代理)重新量之后发现:普通模式 14.1%,常亮 2.9%,本来就只有 1/5;
  砍掉环只从 3.01% 降到 2.91%。0.1 个百分点换掉一个可见特征不划算,环留着。
  两种度量的差异和这个决定都写进了代码注释和 README。

其它
  - LICENSE(MIT)。只覆盖代码 —— design/ 下的设计稿版权归第三方,
    发布前需取得原作者授权或替换视觉,文件内已注明。
  - UserProfile.getProfile() 加异常保护(这个 API 家族已经坑过三次)
  - CHANGELOG.md,版本号 1.0.0 → 1.1.0

验证:55 款全部编译通过(分三批 18+18+19);.iq 上架包可正常导出。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 11:27:54 +08:00

24 KiB
Raw Blame History

Fenix 8 V3 — Garmin 数据表盘

watchface-kit 设计稿 1:1 还原的多指标数据表盘。设计画布 500×500,渲染时按屏宽等比缩放 s = screenWidth / 500,支持圆形 AMOLED 与圆屏 MIP 共 55 款设备Fenix 7/8 全系含 Pro、Epix 2、Enduro 3、Venu 2/3、FR 系列、Approach S50/S70、Descent、D2、Instinct 3 AMOLED 等)。

  • SDKConnect IQ SDK 9.1.0monkeyc 9.1.0minSdkVersion="4.2.0"
  • 语言Monkey C界面文案含英文与简体中文
  • 类型watchface
  • 应用 IDf8a3c1b2c3d44e5f8a9b0c1d2e3f4a5b

设计稿本体7 张 SVG + tokens + 逆向脚本)在 design/,是本仓库所有坐标与配色的唯一来源。


1. 目录结构

fenix8v3-watchface/
├── manifest.xml              # 应用清单ID / 支持设备 / 语言)
├── monkey.jungle             # 构建配置
├── design/                   # ⭐ 设计稿原件(唯一事实来源)
│   ├── watchface-0N-*.svg    #    7 套主题的矢量还原稿
│   ├── watchface-tokens.json #    配色 token
│   └── rebuild.py            #    原作者从位图逆向出 SVG 的脚本(仅存档,不参与构建)
├── tools/
│   ├── gen_themes.py         #    design/*.svg  ->  source/Themes.mc
│   ├── gen_fields.py         #    字段表 -> FieldTable.mc + settings.xml + 两种语言文案
│   ├── gen_devices.py        #    扫描 SDK -> manifest 机型列表 + monkey.jungle
│   ├── gen_icons.py          #    design/*.svg  ->  各尺寸图标位图 + 启动图标
│   └── gen_preview_svg.py    #    source/Themes.mc -> preview-themes.svg + preview.html
├── source/
│   ├── Fenix8V3App.mc        #    应用入口12 行壳子)
│   ├── Fenix8V3View.mc       #    绘制顺序:进度环 / 各元素 / 常亮模式
│   ├── Layout.mc             #    500 画布常量、缩放、字号选择、文字绘制
│   ├── Icons.mc              #    图标:位图三件套 + 其余图元
│   ├── Fields.mc             #    125 项数据字段的取值与格式化
│   ├── Solar.mc              #    日出/晨昏蒙影/黄金蓝调时刻的太阳高度角计算
│   ├── Owm.mc                #    OpenWeatherMap 缓存读取
│   ├── Comp.mc               #    系统 / 第三方 Complication 桥接
│   ├── Fenix8V3Background.mc #    后台服务:拉取 OWM
│   ├── Settings.mc           #    所有设置项的读取与默认值
│   ├── FieldTable.mc         #    ⚠️ 自动生成:字段 id 表
│   └── Themes.mc             #    ⚠️ 自动生成:七套主题配色
├── resources/                #    英文文案 + 设置项定义(部分自动生成)
├── resources-chn/            #    简体中文文案
├── resources-icons-<宽度>/    #    ⚠️ 自动生成:按屏幕尺寸光栅化的图标
├── resources-launcher-<尺寸>/ #    ⚠️ 自动生成:各尺寸启动图标
└── bin/                      #    编译产物(已 gitignore

重新生成全部派生文件:

python3 tools/gen_devices.py \
  && python3 tools/gen_themes.py && python3 tools/gen_fields.py \
  && python3 tools/gen_icons.py && python3 tools/gen_preview_svg.py

gen_devices.py 要先跑 —— 它决定了需要哪些图标尺寸,gen_icons.pyWIDTHS / LAUNCHER 两张表必须跟它对齐,少一档就会有机型编译不过。

三份渲染实现(表盘 / SVG 预览 / HTML 预览)只有 一份颜色数据Themes.mc。预览脚本直接解析它,不会与固件漂移。字段表、设置项、两种语言的文案同样只有 tools/gen_fields.py 里那一张表。


1.5 代码结构

一句话:位置归 Layout,内容归 Fields,配色归 Themes,设置归 SettingsFenix8V3View 只剩画的顺序。

模块 负责 不负责
Layout 500 基准画布的全部坐标常量、px() 缩放、极坐标换算、字号选择与自动缩字、渐变文字的分带绘制 具体画什么
Icons 三个位图图标的加载与染色、电池、蓝牙、其余数据项的图元 图标该出现在哪个数据位(由字段 id 决定,但查表在这里)
Fields 75 项字段的取值、单位换算、本地化文案(星期/月份/标签) 排版
Settings 每个设置项的读取与默认值,包含空值回退 设置项的 UI 定义(在 settings.xml
Fenix8V3View onUpdate 的绘制顺序、进度环、常亮模式 以上任何一项的细节

Fields.value() 按分类拆成 7 个函数(dateTime / activity / body / system / environment / weather / custom),每个在不认识 id 时返回 nullvalue() 依次尝试。id 是交错的1、2、3 是活动8、11、12 是身体14 又是活动),所以按区间派发行不通。

Fields.Ctx 每次绘制构造一个,把 ActivityMonitor / Weather / UserProfile / SensorHistory 的查询懒加载并缓存——四个数据位可能都要天气,但只查一次;没有数据位用到 UserProfile 时就完全不查。

2. 布局500 基准,取自设计稿 SVG 路径的墨迹包围盒)

元素 位置 说明
进度环 内半径 231.09,外半径 249.10 见 §3
电量图标 x=192.70cy=53.2026.20×17.81 圆角外框 + 按电量填充 + 右侧触点
电量数值 左对齐 x=232.00 NN%
上方双数据 图标 cy=90,数值 cy=131.06;左 x=157.00,右 x=343.70 居中对齐
时间 cy=221.10;小时右对齐 x=211.40,分钟左对齐 x=276.02 竖向渐变,见 §4
冒号 x=237.8824.24×21.30y=183.68 / 234.57 两块矩形
日期带 y=286.30,高 44.19,文字 cy=308.10 蓝牙 cx=36.88、星期 cx=178.05、月日 cx=298.28、AM/PM 右对齐 465.89
底部数值 cy=366.76;左格右对齐 234.30,右格左对齐 267.40 过宽时自动降一档字号
底部标签 cy=410.88,同上对齐 跟随所选数据(DST / STEP / 距离 …)

字号按设计稿的**字面高度cap height**选取:日期带与电量 25.34、上方数据与底部行 31.50、时间 98.70


3. 进度环

刻度是等角宽的环形扇区fillPolygon 四点),不是径向线段。

  • 顶弧21 根,角度 6.5 + 4.0kk=0..20),角宽 3.108°
  • 底弧21 根,角度 6.005 + 3.0k,角宽 2.086°
  • 四象限:右上 +a、左上 -a、左下 180+a、右下 180-a(角度为自 12 点起顺时针)
  • 锚点圆点:半径 9.00,位于圆心距 240.10、角度 0 / 93.15 / 180 / 266.85

点亮方向(与设计稿一致):两条顶弧从 9 点 / 3 点一侧朝 12 点填充;两条底弧从 6 点朝两侧填充。

每根刻度的颜色是设计稿里逐根取样的实测值(Themes.RINGTOP[21] / RINGBOTTOM[21]),不是插值近似。

已知近似:设计稿中底弧最多只点亮 14/21 根,因此 RINGBOTTOM 的第 1521 项无法实测,由 gen_themes.py 对最后 8 根做最小二乘线性外推得到。只有当指标超过约 67% 时才会显示这几根。

指标进度换算

idx 指标 分母
0 步数 stepGoal
1 卡路里 固定 2000 kcal
2 距离 10 km
3 楼层 floorsClimbedGoal(缺省 10
4 动动条 MOVE_BAR_LEVEL_MAX=5

4. 时间数字的竖向渐变

设计稿的小时 / 分钟数字带竖向多段渐变(如 Ember 分钟由 #FEAA00 渐变到 #FF2600。Monkey C 无法给文字直接填渐变,实现方式是同一串数字画 11 遍,每遍用 dc.setClip 限制在一条横向色带内,色带颜色取自 Themes.HOURS / Themes.MINUTES(各 11 个停止点,实测自设计稿的 linearGradient)。首尾两条色带向外延伸,保证字形不会有未绘制的缝隙。


5. 字号选择

Connect IQ 只暴露 getFontAscent / getFontDescent / getFontHeight没有字面高度接口,而 ascent 里含有数字和大写字母用不到的变音符空间。因此代码用两个实测比例把 ascent 折算成 cap height

文本字体Roboto 系)  cap ≈ 0.76 × ascent
数字字体Bionic 系)  cap ≈ 0.71 × ascent

比例是在模拟器里渲染后、从截图上量出墨迹得到的fenix847mmFONT_XTINY ascent 29 → 大写高 22pxFONT_NUMBER_MILD ascent 82 → 数字高 58pxpickFont 取折算后最接近目标 cap height 的字体,而不是"最大且不超过"——后者会在设计尺寸落在两档字体之间时白白小一号。

各机型内置字体不完全相同Roboto-Regular / RobotoCondensed-Bold / Yantramanav / 各机型位图字体),比例会有几个百分点误差。设计稿使用的是更粗更方的第三方字体,不随包分发,字形差异无法消除。


6. 七套主题

tools/gen_themes.pydesign/watchface-0N-*.svg 生成。每套包含:顶/底弧各 21 根刻度色、未点亮刻度色、锚点色、日期带底/字色、冒号色、小时/分钟各 11 段渐变、强调色(图标与 DST/STEP 标签)、主文字色(各项数值)。

# 主题 主色调 强调色 日期带
1 Ember 黄 → 红 #FEAA05 橙底黑字
2 Aurora 黄绿 → 青 #ADABAE 深灰底白字
3 Brass 金铜 #B57E4B 深棕底白字
4 Voltage 蓝 → 黄 #ADABAE 蓝底黑字
5 Reef 橙 → 青 #FEAA05 青底黑字
6 Acid 黄绿(近单色) #C6FA03 深灰底黑字
7 Kelp 橙 → 绿 #34C294 深灰底黑字

改配色:编辑 / 替换 design/ 里的 SVG然后

python3 tools/gen_themes.py && python3 tools/gen_preview_svg.py

新增主题需同步在 settings.xmlTheme 列表与 strings.xml(含 resources-chn/)中登记。


7. 可配置设置与数据字段

19 项设置,在 Garmin Connect 手机 App 的「表盘设置」里改(定义在 resources/settings/settings.xml,默认值在 properties.xml,两者由 tools/gen_fields.py 生成)。

设置 默认
主题 Theme 1 (Ember)
四段进度环指标 RingTR/TL/BR/BL 步数 / 卡路里 / 动动条 / 楼层
四个数据位 LeftTop RightTop BottomLeft BottomRight 日出 / 高低温 / 距离 / 步数
温度单位 TempUnit 跟随手表
第二时区 1 / 2 偏移(分钟) AltOffset1 AltOffset2 0
自定义文字 1 / 2 / 3 Custom1/2/3
显示顶行 / 日期带 / 底行 ShowTop ShowBand ShowBottom true

进度环指标:步数、卡路里、距离、楼层、动动条、活动分钟(对周目标)、身体电量。

数据字段

四个数据位共用一张 156 项 的字段表,编号沿用 watchface.io/docs/datafields,两边可以直接对照。底部两格的小标签跟随所选字段自动变化,不需要单独配置。

分类 字段
日期时间 前导零两种、时间、UTC 时间、第二时区 1/2、星期月日、星期日、月日、日、星期简写/全称)、月份(名称/数字、上午下午、周数ISO / 日历)
活动 步数、步数取整、剩余步数、卡路里、活动卡路里、活动分钟(总/中强度/高强度/本周)、距离、上楼层数、下楼层数、爬升高度、推行距离、推行次数、本周 / 近 7 天 / 近 28 天累计(步数/卡路里/距离/楼层/活动分钟)
身体 心率、静息心率、压力指数、血氧、呼吸频率、身体电量、活动条(正/反向、体重、BMI、恢复时间、最大摄氧量跑/骑)
系统 电量、剩余天数、电量+天数、闹钟、通知、勿扰、蓝牙、太阳能强度
环境 海拔、海平面气压、环境气压、日出、日落、下一太阳事件、距太阳事件、月龄、月球照明、民用/航海/天文晨昏蒙影(各 2 项)、黄金时刻(晨/昏)、蓝调时刻(晨/昏)
天气 气温、最高/最低、体感、最高、最低、湿度、降水概率、风速、风向角、风向、更新时间、海平面气压、紫外线、能见度、露点
OpenWeatherMap 气温、体感、最高/最低、天气描述(简/详、湿度、气压、能见度、风速、风向角、风向、阵风、1h 降雨、1h 降雪、云量、降水概率、露点、明日与后日气温及高低温、城市名、更新时间、空气质量AQI 等级 + 描述 + PM2.5 + PM10 + CO(共 30 项)
系统 Complication 下一个日程、训练状态、完赛预测5k/10k/半马/全马)、配速预测(同上四项)、最近高尔夫得分、本周跑步距离、本周骑行距离、第三方 App 15
自定义 自定义文字 1 / 2 / 3、自定义时间格式、日期格式 1 / 2、事件倒计时

加字段:在 tools/gen_fields.pyFIELDS 表里加一行,跑一遍生成器,再到 source/Fields.mcvalue() 里补一个分支。设置项、两种语言的文案、表盘标签会自动跟上。

系统 Complication

Toybox.ComplicationsCIQ 4.2+17 款设备全都有)让表盘可以订阅系统和其它 App 发布的复杂功能。这条路解锁了一批原本以为做不到的字段:

  • 日历事件 —— CIQ 确实没有日历 API但系统把「下一个日程」作为 complication 发布了出来
  • 训练状态、完赛/配速预测、最近高尔夫得分 —— ActivityMonitor.InfoUserProfile 上都没有,这里有
  • 本周跑步 / 骑行距离 —— 这是按运动分类的,ActivityMonitor 的按天历史做不出来
  • 第三方 App 15 —— CGM、补水、行情这类 App 发布的复杂功能,按序号取

需要 ComplicationSubscriber 权限。第三方 App 那五个槽位按「有值且有短标签」过滤后按序号取,避免序号随手表上装了什么 App 而漂移。

自定义格式与倒计时

时间/日期格式串用单字母占位符(设置项能填的长度有限,这样中英文都好写):

占位符 含义 占位符 含义
h / H 小时(跟随 12/24 制)/ 补零 D
m / s 分钟 / 秒(补零) M / N 月(数字 / 名称)
a 上午/下午24 小时制下为空) Y / y 四位年 / 两位年
w 星期

其它字符原样输出,所以 D/M10/9w N D周四 9月 10

事件倒计时填 YYYY-MM-DD,显示还剩几天。

秒针与后台天气

850/869通过 onPartialUpdate 每秒重绘:只有当某个数据位真的选了秒时才请求这个回调,并且只在该格的裁剪区内重绘,不动整个表盘。常亮的 AMOLED 机型不参与——那时数据位本来就不显示。

OpenWeatherMap 需要用户在设置里填自己的 API key免费档即可。没填就完全不联网25 个 OWM 字段都显示 --。填了之后由后台服务每 30 分钟拉一次(当前天气 + cnt=16 的短预报,够算出明日/后日高低温),结果压平成一个小字典存进 Application.Storage,表盘只读不联网。

位置来自天气观测点或最近一次 GPS 定位,并缓存在 Storage 里——两个来源都会间歇性为空,缓存让日出和晨昏蒙影不会一会儿有一会儿没有。

⚠️ 仍然没有实现的,以及原因

没做的 原因
按运动细分的多数汇总(游泳、自定义运动 1/2 的距离/时长/次数,约 60 项) ActivityMonitor.getHistory() 只有按天总计,没有按运动分类的历史。跑步和骑行的本周距离例外——系统把这两项作为 complication 发布了,已经做了;游泳和自定义运动没有对应的 complication 类型
日历事件、计时器 日历已通过 Complication 做了。计时器仍然做不了:表盘拿不到触摸输入,没法启停
StormGlass.io 潮汐5 项) 需要额外的付费 API key且与本表盘的定位无关
第三方 App 复杂功能CGM、Hydration、QuoteGlance 等 12 项) 需要用户装了对应的 App并通过 Complications API 订阅
睡眠得分 ActivityMonitor.Info 上没有,也没有对应的 complication 类型SDK 9.1.0 实测)。训练状态与完赛/配速预测已改由 Complication 提供
高尔夫成绩 无对应 API
标记类字段Marker约 35 项) 那是给刻度型表盘做环形标记用的,本表盘的进度环用的是自己的指标体系
OWM 的 UVI 要 One Call 3.0 订阅。AQI 已经做了——空气质量走 /data/2.5/air_pollution,那个接口在免费档就开放。露点用 Magnus 公式从温湿度算出

8. 数据来源与权限

元素 API
步数 / 卡路里 / 距离 / 楼层 / 动动条 / 活动分钟 / 呼吸 / 压力 / 恢复时间 ActivityMonitor.getInfo()
心率 Activity.getActivityInfo().currentHeartRate,回退 ActivityMonitor.getHeartRateHistory()
血氧 / 身体电量 SensorHistory(需 SensorHistory 权限)
静息心率 / 体重 / 身高 / 最大摄氧量 UserProfile.getProfile()(需 UserProfile 权限)
海拔 / 环境气压 / 海平面气压 Activity.getActivityInfo()
日出 / 日落 Weather.getSunrise/getSunset(location, time),位置取 CurrentConditions.observationLocationPosition,回退 Activity.currentLocation
气温 / 体感 / 湿度 / 降水 / 风 Weather.getCurrentConditions()
最高 / 最低气温 Weather.getDailyForecast()[0]
电量 / 剩余天数 / 太阳能 System.getSystemStats()battery 是 0100 的百分比,不是 01
闹钟 / 通知 / 勿扰 / 蓝牙 / 单位制 System.getDeviceSettings()
月龄 / 月球照明 自算(儒略日 + 朔望月 29.530588853 天)
周数 自算ISO 8601 与日历周两种)

权限

manifest.xml 声明五项:UserProfile静息心率、体重、VO2maxSensorHistory(血氧、身体电量)、CommunicationsBackgroundOpenWeatherMapComplicationSubscriber(日历、训练状态、第三方 App。用户安装时会看到授权提示。

Sensor 权限不能用于 type="watchface"(除非同时申请 Background),编译器会直接拒绝。所以海拔与气压走 Activity.Info 而不是 Sensor.getInfo()

单位与制式跟随手表:is24HourdistanceUnitstemperatureUnits(温度可用 TempUnit 覆盖)。天气与日出需手表已配对并同步过数据,否则显示 --


8.2 常亮显示AOD

AMOLED 机型在常亮模式下必须压低点亮像素否则既费电又有烧屏风险Garmin 上架审核也会卡。onEnterSleep / onExitSleep 切换到 drawAmbient()

  • 不画日期带底色(整条亮橙色横幅是最费电的元素)
  • 进度环只画点亮的刻度,且整体压暗到 45%
  • 时间与日期压暗到 55%,其余数据位全部隐藏
  • 整个画面按分钟在 ±4px 内游走,避免固定像素长期点亮

只在 DeviceSettings.requiresBurnInProtection 为真时启用MIP 机型不受影响,照常全量绘制。

实测fenix847mm取表盘内区

点亮像素数 平均亮度(功耗代理)
普通模式 27.6% 14.1%
常亮模式 10.4% 2.9%

两个口径差别很大:「点亮像素数」把每个抗锯齿边缘像素都算成亮的,和实际功耗对不上。曾试过连进度环也砍掉,平均亮度只从 3.01% 降到 2.91% —— 0.1 个百分点换掉一个可见特征不划算,所以环保留。

模拟器可用 Settings → Display Mode 切换验证。


8.5 多语言

manifest.xml 声明了 engchn,两套文案分别在 resources/strings/resources-chn/strings/,由 monkey.junglebase.resourcePath = resources;resources-chn 同时纳入编译(目录名的 -chn 后缀就是语言标记)。手表会按系统语言自动选择。

表盘上的文字也走资源,不是硬编码:

资源 英文 中文
DowNames SUN,MON,…,SAT 周日,周一,…,周六
MonNames JAN,FEB,…,DEC 1月,2月,…,12月
DateFormat $1$ $2$SEP 9 $1$$2$日9月9日
Meridiem AM,PM 上午,下午
FieldLabels TEMP,KCAL,STEP,DST,… 气温,卡路里,步数,距离,…

逗号分隔的列表在 loadStrings() 里一次性读入并拆分(loadResource 每次调用开销不低,不宜放进 onUpdate)。

中文字形依赖手表固件里的 APAC 字体包(fontSet: apac_twcn / apac_chn)。国行机型自带;国际版若未安装中文字体包,会退回英文或显示方块。模拟器可用 Settings → Language → Chinese (Simplified) 验证。


9. 构建

需安装 Connect IQ SDK 9.1.0monkeyc 在 PATH 中,并备好 developer_key.der不在仓库内,需自行生成或提供)。

monkeyc -o bin/Fenix8V3.prg -f monkey.jungle -y developer_key.der -d fenix847mm

全部 17 款设备批量编译(已验证通过):

for d in enduro3 fenix843mm fenix847mm fenix8pro47mm fenix8solar47mm fenix8solar51mm \
         epix2 epix2pro47mm epix2pro51mm fenix7 fenix7x fenix7s fr965 fr265 fr255 \
         venu3 vivoactive5; do
  monkeyc -o "bin/Fenix8V3_${d}.prg" -f monkey.jungle -y developer_key.der -d "$d" \
    && echo "[$d] OK" || echo "[$d] FAIL"
done

屏幕分辨率跨度较大FR255S 218×218 至 454×454 共 8 档),全部按 s = width/500 缩放。

机型列表和 monkey.jungletools/gen_devices.py 扫描本机已安装的 SDK 设备生成:筛选条件是「支持 watchFace + 圆屏 + CIQ ≥ 4.2」Complications 需要 4.2)。注意结果取决于本机装了哪些设备,跑之前先确认 SDK 设备装全了,脚本会打印找到的数量。


10. 模拟器与侧载

connectiq &                                        # 启动模拟器
monkeydo bin/Fenix8V3_fenix847mm.prg fenix847mm    # 载入表盘

非 release 编译会同时产出 bin/*-settings.json,可在模拟器 View → Settings 载入以实时切换主题与指标。注意模拟器会持久化已保存的设置,改 properties.xml 的默认值对已运行过的实例不生效,需先重置应用数据。

真机侧载:用 Garmin Express 或 Connect 手机 App 导入对应机型的 bin/Fenix8V3_<device>.prg,或把 .prg 拷入手表 /GARMIN/Apps/


11. 预览

python3 tools/gen_preview_svg.py

产出 preview-themes.svg(七套主题一览)与 preview.html(可切换主题的单页)。两者用网页字体渲染文字,几何与配色可信,字形不可信 —— 真机字形以模拟器截图为准。


12. 与设计稿的差异

  1. 字体。设计稿用的是一款更粗、更方的第三方字体Garmin 只提供内置 Roboto / Bionic 系列,且各机型不同。字号按 cap height 对齐,字形无法一致。
  2. 图标。设计稿里的图标是位图描出的密集矢量路径(数百个点),不适合逐帧绘制;代码用圆、多边形、线段按实测的子形状位置重建了电量、日出/日落、多云三个图标。其余数据项(卡路里 / 步数 / 距离 / 楼层)设计稿未提供图标,为自绘。
  3. 底弧高段颜色为外推值,见 §3。
  4. 进度环是实时数据,设计稿中的是固定演示状态(右上 21/21、左上 10/21、右下 9/21、左下 14/21

13. 设计稿版权

design/ 内的 SVG、tokens 与 rebuild.py 来自 watchface-kit,版权归原作者所有。本仓库是按该设计稿实现的 Monkey C 表盘。