Communitygithub.com

hirowyh/settle

根据文字描述,构建一个带有细腻动效的界面组件,视觉风格每次独立创作。

settle 是什么?

Settle 是一个专注于构建单一、带有物理质感动效的界面组件的 AI Agent 技能。它能够将诸如“一个按起来手感很棒的开关”或“展示待办事项应用的循环动画”这类模糊或具体的需求,转化为一个独立的 HTML 文件或集成到现有项目中的组件。该技能的核心在于其独特的运动机制(基于 `settle.track`、`settle.stretch` 等内核函数),确保所有动效都遵循物理世界的惯性、弹性和阻尼规律,而非简单的线性动画。每次构建时,Settle 会根据请求或项目现有风格,通过其 `scripts/deal.mjs` 脚本随机生成一套全新的视觉外观(包括调色板、排版和方向),确保每个产出的视觉都是独一无二的。此技能适用于 Cursor、Claude Code 等支持 AI Agent 的开发环境,要求环境中有 Node.js 22+ 和 Chromium 浏览器以执行构建和检查步骤。它特别强调“每次只构建一个组件”,拒绝构建完整页面或网站,专注于提升单个交互元素的设计品质。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/hirowyh/settle/tree/main/skills/settle

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

settle 是做什么的?

将诸如“一个按起来手感很棒的开关”或“展示待办事项应用的循环动画”这样的请求,转化为一个带有物理质感动效的成品组件。其动效工艺在所有组件上保持一致;而外观则每次根据请求独立创作,或继承自用户的项目。

以下路径均相对于此文件所在的文件夹。请从工作文件夹(项目的根目录,或组件所在的文件夹)运行每个脚本,使用其完整路径,如 node <此文件夹>/scripts/deal.mjs …:脚本会将生成的文件写入您运行命令的位置。

请求处理流程

  1. 阅读上下文。 确定您是否处于一个项目中:一个包含框架信息的 package.json 文件,或一个包含 HTML 页面的文件夹。如果在一个项目中,注意其编写样式的方式、其设计令牌或主题设置的外观,以及它已使用的动效库。然后阅读请求:判断它属于 references/kinds/ 中的哪种结构,是一个演示品还是产品的一部分,以及其模糊的措辞想要什么,这些措辞的含义由 references/words.md 翻译。
  2. 创作或继承外观。
    • 一个有自己外观的项目会保留其外观:将该外观映射到样式表的变量上,并仅使用 --keep palette,type 创作其缺失的部分。
    • 否则,创作外观:运行 node scripts/deal.mjs --brief "<一行描述的请求>" --kind <control, data-view, composite 或 flow>,并带上 references/words.md 根据请求措辞提供的标志,如果处于项目中则加上 --project,以便后续组件继承该外观。构建外观 1,即创作好的外观:--pick 1。仅当外观 1 与主题冲突时才选用外观 2 或 3,并说明冲突原因:--pick 2 --because "早餐菜单的深色背景"。references/tokens.md 包含了相关规则。
    • 创作好的外观有一个方向,它决定了组件的视觉风格;请求则设定其形式。阅读其在 references/directions.md 中的章节。每个方向在章节顶部,位于简要描述之前。
  3. 撰写简要说明或故事板。
    • 对于控件、数据视图或复合组件,用两行陈述简要说明并直接构建:说明它是什么、该方向如何适用于此主题、外观是什么、标志性时刻是什么以及您选择的默认值。“一个学习网站的番茄钟。结构:计时器采用厨房计时器的表盘设计,表圈上刻有分钟刻度;外观 1,浅灰色和黑色;标志性时刻:开始按钮变成倒计时进度条;25 分钟工作,5 分钟休息。”
    • 对于随时间变化的流程,或可能有两种截然不同含义的请求,请展示故事板(references/kinds/flow.md 中有格式)并等待确认。
    • 在构建之前,设想任何类似请求会得到什么结果。修改简要说明中与设想结果匹配的部分。
  4. 在组件所在位置进行构建。
    • 没有项目时: 基于 assets/page.html 的单个 HTML 文件,或者 assets/reel.html 用于动画短片。它包含样式表、方向的页面规则、完整粘贴到 head 模块脚本中的内核 (assets/kernel.js),以及 references/motion.md 中该组件所需的配方。
    • 在一个项目中: 使用项目框架和样式的组件,内核作为模块复制一份,样式表放入项目的全局样式表中。references/stacks/ 为每个技术栈提供一个说明。
    • 为已有组件添加动效: 保留其标记和外观,并为其每次状态变化赋予动效语法所命名的运动(references/craft.md,第 3 节),通过门控实现。
    • references/kinds/ 中的结构文件,会根据每个部分变化类型,说明应从哪个配方开始。
  5. 检查它。 对文件进行 lint 检查,并使用 snap.mjs 按照 references/review.md 的描述截取帧,可以针对文件或项目的开发服务器。修复联系表中看起来不对劲的地方,然后再次截取,最多进行三轮。对于表现不佳的检查,例如拖拽无法吸附或服务器无法启动,给予两次尝试机会;然后将其标记为“未检查”后进行移交。
  6. 移交(见下文)。

需要阅读的内容

文件何时阅读
references/craft.md每次构建:每个运动遵循的规则、禁用列表和注意事项
references/tokens.md每次构建:外观如何被创作或继承,以及如何使用
references/directions.md每次构建(无项目):创作方向的对应章节
references/motion.md每次构建:样式表、基础页面和配方,每种动效一个
references/kinds/control.md, data-view.md, composite.md, flow.md组件的结构:其基本结构和应起始的配方
references/stacks/html.md, react-next.md, vue.md, svelte.md, astro.md组件所处的位置:独立文件使用 html.md,否则使用项目技术栈的说明
references/words.md请求描述了一种感觉,例如“让它更突出”
references/review.md检查步骤

硬性规则

  • 组件放在用户工作的地方。 在项目中:使用项目的框架和样式,不引入新包,并使用项目自身的动效库(如果有的话),同时应用 settle 的计时。没有项目时:一个自包含的 HTML 文件,内核已粘贴进去,其唯一的外部请求是外观所需的字体链接;并且必须能在系统字体下正常工作。按需获取的照片放在其旁边。
  • 请求设定形式。 控件保持其真实尺寸,小部件保持为一个卡片或面板,只有请求明确要求全屏时才会使用全屏。对于请求完整落地页或网站的请求,仅构建其中的动效组件,例如应用的幻灯片,使其可插入页面,然后将页面设计工作移交给页面设计技能。组件周围的背景保持简洁。
  • 外观来源于样式表和方向。 每个视觉值都来自样式表的变量或其色调,包含一种背景色、一种文字色和一或两种强调色。创作的方向决定了组件的视觉风格,深色背景用于发生在黑暗中的主题。
  • 动效来自内核。 每个响应用户的动作和每个状态变化,都使用 settle.track、settle.stretch 或 settle.move 来执行,并配合外观寄存器中的预设 settle.register()。
  • 时间来自 settle.now()。 事件处理器设定目标;一个 requestAnimationFrame 循环根据当前时间绘制所有运动中的样式。snap.mjs 会停止时钟以检查帧。
  • 形状延续。 每个新状态都是从屏幕上已有的形状构建的,变化的文本会经历短暂模糊,新容器会从背后已有的容器中打开。
  • 手动拖拽优先。 被拖拽的值精确地停在指针下;超出限制后则遵循橡皮筋效果;释放时保留手部的速度。
  • 真实内容。 使用合理且具体的示例,在一个流程中动作保持其名称。照片来自用户,或者当用户要求真实照片且没有提供时,从 scripts/photo.mjs 获取,并在组件中注明来源;否则仅用代码绘制代码能清晰绘制的内容,绝不绘制风景(references/directions.md,图片部分)。
  • 一个标志性时刻,且其周围的一切都保持安静。
  • 除非请求指明,否则禁用: references/craft.md 中禁用列表的所有项目,lint 工具会标记它们。
  • 为所有人设计。 支持指针、触摸和键盘操作,具有可见的焦点状态和 44 像素的交互目标。适应 360 像素宽的屏幕,最小字号不低于 11 像素;在减少动效模式下,其弹簧效果会立即停止。
  • 成本意识。 每次工具调用都会消耗用户的配额。构建一次,最多检查三轮,给予表现不佳的检查两次尝试机会,并且不要调试脚本本身:在移交时说明哪些项目未经检查。

演示品或产品

演示品,例如用于落地页的动画短片,会获得完整的动效。产品内部的控件,随着用户看到它的频率增加,其动效会减少:每天使用上百次的组件没有动效,每天使用几十次的组件使用快速而轻微的效果。references/craft.md 中有相关表格(Emil Kowalski 的频率规则)。

文件存放位置

没有项目时,在工作文件夹下,根据主题使用简短名称(如 tea-timer.html)创建文件,除非用户指定了路径。在项目中,按照技术栈说明中的位置放置,使用项目自身的命名风格,并确保用户可以打开它:如果请求未指定,则放在一个独立的页面或路由上。将组件中可调整的数值集中放在脚本顶部:包括数据,以及寄存器未设定的任何计时。

移交

回复时包含:

  • 组件的位置,如何打开它(文件,或路由及启动开发服务器的命令),以及一行说明它是什么及其标志性时刻。
  • 两到三个值得尝试的操作:“将旋钮拖过末端”,“按 Tab,然后按方向键”。
  • 两个可微调的参数,以脚本顶部的变量名给出。
  • 当有代码绘制的占位图时,说明用户照片的放置位置:应将哪个元素替换为用户提供的 <img>。
  • 有哪些内容未经检查,例如在真实手机上的 Safari 浏览器中的表现。
  • 提供重新创作部分外观的选项(node scripts/deal.mjs --redeal palette),对于模糊的请求,提供一个带三个变体的切换器。

对于动画短片,提供视频导出选项:node scripts/export.mjs reel.html --out reel.mp4(或 --gif)使用 ffmpeg 渲染它,平均每个帧四个子帧以实现运动模糊。

脚本

脚本功能
scripts/deal.mjs --brief "…" [--tone …] [--register …] [--dark] [--project]创作三个外观;--pick <n> 打印选定的样式表(并使用 --project 将其保存为项目的外观);--redeal <part> 重新创作某一部分;--check 检查库
scripts/lint.mjs <file>对独立文件进行静态检查;FAIL 时返回退出码 1
scripts/snap.mjs <file or url> --out <dir> --sheet [--size WxH] [--times …] [--do "…"] [--calm]在停止的时钟上截取帧,带有真实输入和联系表,然后执行其标题中列出的已定稿页面的检查
scripts/export.mjs <reel> [--out reel.mp4] [--gif]将动画短片导出为 MP4 或 GIF,带有四子帧的运动模糊
scripts/photo.mjs "<展示内容>" [--out photo.jpg]获取一张开放许可的照片(CC0、公共领域或 CC BY),保存到运行位置,并提供用于组件的署名信息;仅当用户要求真实照片时使用

它们需要 Node 22 或更高版本以及一个 Chromium 浏览器:snap.mjs 会在常用位置找到 Chrome、Chromium、Edge 或 Brave,其他浏览器通过 CHROME 环境变量指定。当找不到任何浏览器时,它会用一行说明;请对照 references/review.md 审查代码,并将帧标记为未经检查。导出还需要 ffmpeg,photo.mjs 需要网络连接。无需安装任何其他东西。

无 Shell 环境

当无法运行脚本时,例如在无法使用 shell 的聊天环境中:读取 library/directions.json、library/palettes.json 和 library/type.json,保留其种类和色调与请求匹配的条目,并取请求字符长度在环绕每个列表的位置对应的条目,以便不同的请求落在不同的外观上。使用相同的文件进行构建,对照 references/review.md 中的评估标准审查代码,并在移交时说明帧未被检查。

致谢

…

相关技能