关于 interface-bts
interface-bts 是一项技能,可将现有界面交互整理成 A4 规格海报。它引导开发者追踪并测量运行中的组件,再排版和核验海报,不改造组件。
主要功能
- 01追踪交互触发与结果
- 02测量运行中组件的数值
- 03绘制标注与运动曲线
- 04捕捉可选的交互时刻
- 05排版并核验 A4 海报
适用场景
- 01记录下拉菜单的过渡行为
- 02说明拖动或滚动的输入映射
- 03记录减少动态效果的行为
- 04交付经过测量的界面规格
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nomanjack/ interface-bts --skill interface-bts安装后在 Claude Code 中输入/interface-bts确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdLICENSEassets/example/copy.module.csscopy-spec-sheet.tsxsource-copy.tsxassets/kit/sheet-states.tsxsheet-states.module.csssheet-playback.module.csssheet-playback.tsxsource-kit.tsspec-kit.tsxspec.module.cssreferences/drafting.mddrivers.mdscripts/overlaps.js详细介绍
interface-bts
这项技能会将项目中的一次交互转化为一张 A4 规格海报,描绘其背后的运行机制。海报包含:
- 图 1: 组件的真实样貌,定格在动作进行中,并标注尺寸。
- 标注: 带编号的部件,并附上说明,解释各部件会发生什么变化以及原因。
- 图 2: 驱动组件变化的曲线或映射关系。
- 时刻: 一排可供选择的时刻,选中后可让组件重新演示。
- 规格: 触发条件、属性、时长、缓动方式和减少动态效果的处理。
读者看完后,应该能用一句话说明它的工作原理。
这张海报记录的是界面当前的行为。它不是重新设计、实时调试叠层或视频。如果有人想修改组件,请明确说明,并不要把修改内容放进海报。海报上的每个数字都来自正在运行的组件;无法读取的数值会标为估算值,绝不凭空填写。
示例:/interface-bts the dropdown in components/menu.tsx
1. 研究交互
- 找到组件、调用它的代码、样式、事件处理器和动画代码。运行项目并亲自操作。
- 追踪输入 → 决策 → 输出:
- 是什么触发了它?
- 发生了什么变化?
- 哪些值驱动了变化(时长、缓动方式、阈值、尺寸)?
- 每个值定义在哪里?
- 探查能体现规则的情况:缓慢输入、反向操作、中断、静止状态以及减少动态效果的情况。
完成标准: 你能用一句话说清楚其运行机制,并指出所用每个值的来源。
2. 在聊天中确认海报方案
列出以下内容,并等待对方确认后再开始制作:
- 标题: 用通俗的话说明运行机制(“胶囊会追上来:它的左边缘和宽度沿同一条曲线缓动”)。
- 主视觉时刻: 最能展现运行机制的画面。通常选动作进行到一半或刚越过阈值时的画面,很少选静止状态。
- 时刻: 按故事顺序排列 3–5 个时刻(静止、开始、主视觉、越过阈值、稳定)。
- 标注: 图 1 中 2–4 个带编号的部件,并说明每条标注的内容。
- 图 2: 从下表中选择一种。
- 测量: 标题所依赖的一两个尺寸。
| 解释内容 | 图 2 绘制内容 |
|---|---|
| 数值如何随时间变化(大多数过渡) | 缓动曲线,并在曲线上标出当前时刻 |
| 同一时间轴上的两个变化(交叉淡化、图标切换) | 在同一时间轴上绘制两条曲线 |
| 随输入变化的数值(拖动、滚动) | 输入到输出的映射,并标出限制值和吸附点 |
| 关键帧或循环 | 一个周期内各关键帧的停留位置 |
| 阈值或吸附 | 决策区间,并在其中标出当前输入值 |
完成标准: 用户已确认标题和各个时刻。
3. 冻结真实组件
- 图 1 是真实组件。 使用它自己的处理器驱动它,并通过暂停其真实动画来冻结它:调用
getAnimations(),然后调用pause()并设置currentTime,或定位到动画库自身的时间轴。绝不要重建组件,也不要运行第二个动画来模仿它。 - **从运行中的组件读取每个数值:**计算样式、
getAnimations()、时间轴,或组件公开的数据属性。绝不要在海报中手动填写时长、缓动函数或阈值。使用firstEasing()获取第一个缓动函数:按逗号拆分计算后的列表会把cubic-bezier()拆成两半。 - **非 CSS 过渡的组件需要专属驱动器,**而且有些组件会与海报发生冲突:由 floating-ui 放置的元素(Radix 菜单、弹出框、工具提示)、固定在窗口上的元素(通知、抽屉)、在屏幕上测量自身的元素(拖动和滑动阈值),或会移动焦点的元素。在构建这类驱动器前,请阅读 references/drivers.md。
- **在将多个通道呈现为同一种机制前,先确认它们彼此一致,**例如确认不透明度与缩放遵循相同的曲线。如果不一致,海报应显示错误状态,而不是错误的图示。
- **每个时刻都是副本:**带有内联计算样式的静态 DOM 快照,且处于非活动状态。所有时刻都使用同一相机,避免增长看起来像缩小。
- **如实报告测量结果,**即使结果与代码的预期相矛盾。
**完成标准:**每个时刻都能反复将组件驱动到同一帧,保持的数值与源组件一致,并且(对于驱动的手势或指针路径)至少有一次运行已通过真实浏览器鼠标或触摸进行验证。
4. 排版海报
- **始终采用 A4 纵向版式。**先在 794 × 1123 的画板上排版一次(96 dpi 下的 A4),然后整体缩放海报以适应可用空间,并居中放置。绝不在断点处重新排版:调整大小只改变缩放比例,不改变布局。
- **顺序:**组件名称、其下方带有各个时刻的图 1,然后是底部区域。底部区域中,注释和图 2 并排放置,规格说明横跨下方的整个宽度。最底部的标题栏只说明一次单位、绘图比例和线型。
- 字体:
- 名称为 16px、字重 500,是唯一的标题;
- 注释和规格说明为 13/18;
- 图内文字为 12px;
- 只使用一种字体,采用句首字母大写格式,字重不超过 600;
- 数字采用等宽数字,单位的字重比数值轻。
- **内边距:**顶部和底部为 20px,两侧为 32px。
- **按可用位置调整每幅图的大小。**测量可用高度,然后选择绘图比例,使组件及其尺寸标注都能放入。注明比例(“按 3× 绘制”)。
- **不加外框。**注释或图形周围不加卡片或方框;使用细线和纯色填充。不使用光晕、大面积模糊阴影,也不通过渐变营造深度。
- 强调色:
- 每张海报使用一种 iOS 26 系统颜色(工具包中的
IOS26),且在项目的所有海报中各不相同。将其记录在SPEC_ACCENTS中。 - 十二种颜色全部用完后,重复使用使用次数最少的颜色。
- 强调色用于线条和填充,运行区域下方使用 12% 的色调。文字使用同色相的较深墨色(明度上限为 0.52),确保黄色和薄荷绿仍清晰可读。
- 每张海报使用一种 iOS 26 系统颜色(工具包中的
- **主题:**使用应用的真实主题。只有当应用本身为深色主题时,才传入
theme="dark",并通过应用自身的机制读取主题。绝不虚构深色主题,也绝不在海报上放置主题切换控件。在确定主题前不要绘制任何内容,并根据主题设置海报的键值,以便主题改变时重新绘制海报并再次复制各个时刻。
关于尺寸标注基准、线型、细节视图和对齐视图的制图规范,请参阅 references/drafting.md。绘图前请阅读。
**完成标准:**海报上的所有内容都有合适的位置,且没有文字覆盖组件。
5. 润色,然后通过测量验证
润色:
- 视觉对齐: 数字位于其首行的基线上,底部各列共用一条首基线,注释和图形的左边缘对齐。
- 同心半径: 绕部件绘制的轮廓,使用该部件按绘图比例换算后的自身半径。任何嵌套元素都使用外层半径减去间隙。
- 柔和收尾: 制图网格沿径向淡出,时刻行两端都淡出。时刻在淡出时会略微模糊。
- 引线 从部件以 45° 延伸;若间隙是唯一清晰的路径,则直线穿过间隙。
- 悬停在注释上时, 所有标有其他注释的部件都会变暗。
验证:
- 重叠: 将
scripts/overlaps.js粘贴到页面中,并针对每个时刻,在 1280×800、1000×760 和 1030×1044 下运行btsOverlaps({ overlay: '[data-poster] svg', subject: '[data-poster] [inert] > *, [data-poster] [data-subject-root]' })。主体应是组件自身的根元素,而不是包围它的图形,否则每个标签都会被视为位于主体上。它必须不返回任何内容。修正放置规则,而不是单独修正某个标签。 - 适配: 在这些尺寸下页面都不应出现滚动,调整窗口大小时只改变缩放比例。
- 时刻: 逐个选择时刻。组件、注释和曲线都应随之变化,控制台也不应出现问题。
- 固定一个与源数据关联的值, 例如海报的时长应与样式表一致。
- 减少动态效果: 海报应如实呈现(如果没有内容移动,就不应显示时刻行)。开启减少动态效果后,检查规格中的声明:应用级规则可能会覆盖库自身的过渡效果。
- 隐藏的标签页: 嵌入式或后台预览可能不会运行 rAF。检查
document.hidden,并使用无头 Playwright 截图。
全部通过所有检查后才算完成。 说明哪些检查无法运行。
工具包
assets/kit/ 是对上述所有内容的 React 和 CSS 模块实现。将它复制到项目中(Next.js 项目放在 app/specs/kit/,其他项目放在 src/specs/kit/),并在其旁边为每张海报创建一个页面。assets/example/ 中有一张已完成的复制按钮海报,可以从它开始。
spec-kit.tsx:-
SpecPage: 海报。属性:accent、name和label;drawing(图 1)、moments、notes、spec行、fig2和units;ready、error和onRetry;theme。
-
useTransitionSpec({ fractions, setup }): CSS 过渡的驱动器。setup(root)返回:base(静止时的值);easing;trigger(组件自身的处理函数);read(运行期间要读取的内容);- 可选的
pick,用于从多个动画中选择。
它会返回:
m:保持的值,包括elapsed、duration、easing和reduced;snapshots、selected和select;ready、error和retry;root:组件包装元素的 ref。
-
绘图:
Overlay;Dim和VDim(尺寸标注);Callout;markClass(线型和剖面线);useCrisp(将细线对齐到设备像素);useDrawingScale,以及用于必须保持屏幕缩放比例为 1 的组件的useScreenScale。
-
图示:
Curve;Timeline;Moments(带有crop,用于只显示发生变化的部分)。
-
读取:
firstEasing、easeAt和easeWords;stopsOf、sampleStops和scaleOf(关键帧:循环动画使用一个周期);within(将框尺寸测量到 0.1px);U和Ut(带有浅色单位的数字)。
-
source-kit.ts:useDataState:驱动状态存储在数据属性中的组件;startWithout:将组件置于起始状态,且不触发过渡;ms:解析 CSS 时间。
sheet-states.tsx: 快照捕获和时刻行;oneCamera(在spec-kit.tsx中)会将逐个捕获的时刻放入同一帧。sheet-playback.tsx: 为支持播放控制的海报提供播放、暂停和慢速播放功能。
对于滚动、手势、指针路径或 JS 动画库,请编写一个与 useTransitionSpec 形状相同、能控制该库自身时钟的小型驱动器:参见 references/drivers.md。在 React 之外,请移植布局和惯例;工具包仅供参考,并非依赖项。
交付内容
提供海报的 URL、其 1280×800 尺寸的屏幕截图,以及标题。然后列出:
- 测量了什么;
- 哪些内容标注为估算值;
- 哪些检查无法运行。