【免费下载链接】RunCatNeo
A cute running cat animation on your macOS menubar.
RunCat Neo是一款 macOS 菜单栏应用:一只可爱的小猫在你屏幕顶部的菜单栏里奔跑,而且——它的奔跑速度会实时映射 CPU 负载。CPU 越忙,猫跑得越快。本文带你用最简单的方式看懂它的源码:从 CPU 数据如何采样,到速度公式如何计算,再到 Core Animation 如何让猫"跑起来",全部讲清楚 🐱
它是什么?先看效果
安装 RunCat Neo 后,菜单栏会出现一个动态图标。除了默认的小猫,还内置了小狗、史莱姆、咖啡、牛顿摆、引擎、麻薯等 8 种"跑者"。
更实用的是,点开菜单栏还能看到系统资源面板(CPU / 内存 / 存储 / 电池 / 网络),以及你自定义的指标卡片:
整体架构:CPU 数据如何变成奔跑的猫?
整个数据流只有一条主线,非常清晰:
SystemInfoKit 采样 CPU ──→ RunnerService 计算速度 ──→ AppState 广播 ──→ RunnerLayer 播放动画RunCat Neo 采用 LUCA 架构,源码分为三层,依赖方向单向:UserInterface → Model → DataSource。本文涉及的三个角色分别在不同层:
| 角色 | 文件 | 职责 |
|---|---|---|
SystemMetricsService | SystemMetricsService.swift | 按间隔(默认 5 秒,可选 3s/10s)采样系统信息 |
RunnerService | RunnerService.swift | 把 CPU 百分比换算成奔跑速度 |
RunnerLayer | RunnerLayer.swift | 用 Core Animation 播放关键帧动画 |
采样入口在 AppDelegate.swift#L57-L63:AppDelegate启动一个任务组,监听systemInfoStream数据流,每收到一次系统快照,就同时做两件事——刷新资源面板指标、更新猫的奔跑速度。
核心公式:CPU 负载如何映射成速度?
打开 RunnerService.swift#L89-L97,最关键的updateRunnerSpeed(from:)方法只有几行:
func updateRunnerSpeed(from cpuInfo: CPUInfo?) { let cpuValue = max(1.0, min(20.0, Float(cpuInfo?.percentage.value ?? .zero) / 5.0)) let speed: Float = if userDefaultsRepository.speedDecreasesUnderLoad { 0.5 * (21.0 - cpuValue) } else { cpuValue } appStateClient.send(\.runnerSpeeds, speed) }拆解一下这段"速度映射"逻辑:
- 除以 5:CPU 百分比是 0–100,除以 5 后得到 0–20 的区间;
- 夹取在 1–20 之间:
max(1.0, min(20.0, ...))保证 CPU 为 0 时猫也不停下(最低速度 1),满载时封顶 20 倍速; - 反向模式:如果用户在设置里开启"负载越高跑得越慢"(
speedDecreasesUnderLoad),则用0.5 × (21 − cpuValue)取反——CPU 空闲时狂奔、繁忙时慢走,风格完全相反; - 广播出去:结果写入
AppState的runnerSpeeds数据流(见 AppState.swift#L35),动画层订阅后即时生效。
对应关系一目了然:
| CPU 占用 | 映射速度(默认模式) |
|---|---|
| 0% | 1(最低速,猫悠闲踱步) |
| 50% | 10(正常奔跑) |
| 100% | 20(极限冲刺) |
这套行为有完善的单元测试覆盖,例如 50% CPU 对应速度 10、满载对应 20(见 RunnerServiceTests.swift#L230-L265)。
动画原理:为什么不直接换图标?
最直觉的实现是每帧替换菜单栏图标。但 RunnerBarView.swift#L24-L32 的注释记录了一个真实的性能教训:逐帧换图标会让菜单栏在明暗两种外观下对状态项截图,常驻消耗 7–8% CPU;而改用 Core Animation 图层方案后只有约 0.1%。
RunnerLayer.swift 的做法是:
- 创建一个
CAKeyframeAnimation,动画属性是contents(图层内容),calculationMode = .discrete(离散模式,逐帧切换),repeatCount = .infinity无限循环; duration = 帧数 / 2,即 5 帧的猫动画一轮播 2.5 秒(setFrames方法,RunnerLayer.swift#L45-L72);- 关键一步在
setSpeed(_:)(RunnerLayer.swift#L81-L94):不重做动画,只改图层的speed倍率。通过同步timeOffset与beginTime,可以瞬间变速且画面不跳帧——这就是"CPU 一变,猫立刻加减速"的底层机制。
动画编排:不同角色为什么跑姿不一样?
内置角色的帧序列不是简单 0→1→2→3→4,而是由 FrameOrder.swift#L28-L41 定义:
case .swing: [0, 1, 2, 3, 4, 3, 2, 1] // 麻薯:左右摇摆 case .pendulum: [0, 1, 2, 1, 0, 3, 4, 3] // 牛顿摆:钟摆往复 case .partyHorn: [0, 1, 2, 3, 4, 4, 3, 2, 1] // 史莱姆:号角式回旋配合 RunnerKind.swift 里每个角色的帧数(猫、狗、史莱姆、水滴、牛顿摆、麻薯各 5 帧,咖啡与引擎 10 帧),就能得到完全不同的"跑姿":猫是匀速前进,麻薯是摇摆,牛顿摆则是钟摆。
打造你自己的跑者
除了内置角色,RunCat Neo 支持自定义跑者:把一组 PNG 关键帧导入,就能让任何角色在菜单栏飞奔(编辑器源码见 CustomRunnerEditorView.swift,自定义帧持久化逻辑在 RunnerService.swift#L121-L136):
此外,它还能监视任意本地 JSON 文件并在面板渲染成卡片(Schema 文档见 CustomMetricsSchema.md),比如接入 Claude Code 状态栏 或 比特币价格。
上手指南:3 步让猫跑起来
- 安装:在 Mac App Store 搜索 "RunCat Neo" 安装(要求 macOS 26 或更高版本);
- 换角色:点击菜单栏图标,在跑者列表里选猫、狗、史莱姆等,或导入自己的关键帧;
- 调手感:在"设置 → 跑者"中可选择"负载高时减速"模式与水平翻转方向,速度映射公式会即时生效。
小结
RunCat Neo 用一条极简的数据流把"系统监控"变成了"桌面宠物":
SystemMetricsService负责采样(3/5/10 秒可选);RunnerService负责映射(CPU ÷ 5,夹取在 1–20,可反向);RunnerLayer负责呈现(CAKeyframeAnimation+ 图层speed倍率,全程约 0.1% CPU);FrameOrder负责个性(不同角色的帧编排跑姿)。
想深入更多细节,可以从 ARCHITECTURE.md 开始,它完整描述了三层架构与数据流约定 🚀
【免费下载链接】RunCatNeo
A cute running cat animation on your macOS menubar.
相关推荐
VS Code 开源 AI 编辑器路线图:Copilot Chat 开源与核心重构全解读
VS Code 开源 AI 编辑器路线图:Copilot Chat 开源与核心重构全解读 2025 年 5 月,VS Code 官方团队发布了《VS Code:
mpv 音视频同步完整指南:4 个场景把音画对齐到毫秒级
mpv 音视频同步完整指南:4 个场景把音画对齐到毫秒级 看剧时女主的口型比声音快了半拍,这就是音视频同步失守。mpv 是命令行媒体播放器,用几个参数就能把音画
音视频RunCat 365终极指南:让可爱小猫在Windows任务栏上奔跑的完整教程
RunCat 365终极指南:让可爱小猫在Windows任务栏上奔跑的完整教程 还在为单调的工作桌面感到无聊吗?RunCat 365为你带来全新体验!这款创新的
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考