Communitygithub.com

运动感觉 (Motion Feels)

用日常语言描述网站动画。人们说出动画应有的感觉(“平静”、“高级”、“像漂浮”、“太跳跃”、“感觉廉价”),此技能将其转化为14种命名感觉,每种都有精确的速度和缓动曲线,包含CSS、GSAP和弹簧值,因此无需理解缓动曲线。还涵盖了何时不进行动画、界面与展示速度、每个品牌的运动调色板、构建规则(性能、减少动画、触摸)以及运动审查清单。

运动感觉 (Motion Feels) 是什么?

这份SKILL.md文档定义了一种名为“运动感觉”的技能,旨在弥合非技术团队成员与前端开发人员之间的沟通鸿沟。它提供了一套标准化的命名感觉,每种感觉都预先绑定了精确的CSS、GSAP和弹簧动画值(如Snappy、Luxurious、Elastic等14种)。该工具的核心价值在于将主观感受转化为精确的技术参数,从而消除反复猜测和迭代。它提供了详细的表格,用于将日常语言(如“高级”、“顺滑”)映射到具体感觉,以及将反馈(如“太快”)映射到可调整的参数(如速度或超调量)。文档还指导如何根据元素可见频率、界面类型与展示类型选择合适的动画程度,并提出了整个网站的2-3种感觉的调色板建议。它强调了与利益相关者非技术性沟通的方法,避免使用缓动曲线术语,而是使用直观的比喻。构建规则涵盖了性能优化(使用transform和opacity)、可访问性(优先考虑减少动画偏好)和移动端触摸交互。该技能对所有基于文本的AI Agent都有效,是Web开发团队的理想参考。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/nusakutnjak/motion-feels/tree/HEAD/skills/motion-feels

在你喜欢的 AI 中提问

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

文档

运动感觉

大多数人叫不出缓动曲线的名字,但他们确切地知道想要什么感觉:平静、有冲击力、高级、俏皮。这些词语对应着几十条曲线,AI会猜测,结果工作就变成了几轮“太快了”、“弹跳少一点”。这项技能为人和你提供了一套共享的名称,每个名称都绑定到精确的值。他们用感觉描述;你来处理数字。

它专为网站设计:营销、作品集、内容和商店网站。对于应用或产品UI,同样的感觉也适用;使用每种速度的快速端。

三个部分:

  • 感觉:如何运动。 速度加上缓动曲线。14种感觉如下。
  • 效果:什么在运动。 遮罩揭示、视差、跑马灯等。参见 references/feeds.md。
  • 旋钮 调整一种感觉:速度、停止、超调、交错、距离、延迟、触发、强度。

用感觉说话,而不是曲线

这个人可能不懂任何运动术语,也不应该需要懂。

  • 永远不要让他们选择 一种缓动、一条曲线、一个贝塞尔或一毫秒数。询问感觉,用日常生活中的画面来描述:“它应该像放下玻璃杯一样轻轻落地,还是像弹簧一样稍微过度然后稳定下来?”
  • 用动画的外观来描述感觉,而不是它是如何制作的:“开始时很快,然后滑行到停止”,而不是“power4.out”。
  • 感觉名称是可选的快捷方式。 顺带提一句(“我将这种感觉称为豪华”),以便他们可以重复使用。永远不要要求他们使用,也不要纠正他们的措辞。
  • 数字放在代码中,再加上一句话给构建或审查它的人:“对于开发者:1.2 秒,cubic-bezier(0.22, 1, 0.36, 1)。”当没有人会用它来构建时,省略那一行,例如当这个人只是在选择方向时。
  • 此文件中的词语是给你的,不是给他们的。 旋钮名称和CSS术语不要出现在你的回复中。说“结尾的小弹跳”(超调)、“一个接一个”(交错)、“它移动了多远”(距离)、“它停止得有多轻柔”(停止)、“一次移动了多少”(强度)、“它从哪里开始生长”(原点)、“对于关掉动画的人”(减少动画)。
  • 一行翻译,然后构建。 不要讲课,也不要耽误工作。唯一的例外是下面表格中标记为“询问”的词,这时需要先问一个简单的问题。
  • 眼见为实。 当他们无法用语言表达时,提供演示页面(assets/feeds-demo.html,在任何浏览器中打开)或构建一个快速的A/B切换开关让他们选择。

14种感觉

感觉看起来像速度CSSGSAP
清爽一个电灯开关:瞬间,干净的停止150 毫秒cubic-bezier(0.33, 1, 0.68, 1)power2.out
利落快速射出并稳稳落地300 毫秒cubic-bezier(0.16, 1, 0.3, 1)expo.out
弹力快速,小小的过冲,然后稳定下来600 毫秒弹簧,弹跳 0.3(CSS中的 linear())无弹簧;最接近 back.out(1.2)
顺滑一扇推拉门:柔和开始,柔和停止500 毫秒cubic-bezier(0.65, 0, 0.35, 1)power2.inOut
轻柔飘入并渐隐至停止700 毫秒cubic-bezier(0.61, 1, 0.88, 1)sine.out
豪华快速启动,长时间缓慢滑行至静止1.2 秒cubic-bezier(0.22, 1, 0.36, 1)power4.out
飘浮一片羽毛:缓慢而均匀,没有明确的开始或停止2 秒cubic-bezier(0.37, 0, 0.63, 1)sine.inOut
戏剧性剧院幕布:蓄势,冲刺,稳定1.2 秒cubic-bezier(0.87, 0, 0.13, 1)expo.inOut
蓄力弹弓:先向后拉,在终点处过冲800 毫秒cubic-bezier(0.68, -0.6, 0.32, 1.6)back.inOut(1.7)
弹出跳过头一次然后回来450 毫秒cubic-bezier(0.34, 1.56, 0.64, 1)back.out(1.7)
弹性果冻:摇晃几下,然后稳定下来1 秒linear() 来自 elastic.outelastic.out(1, 0.3)
弹跳球落地900 毫秒linear() 来自 bounce.outbounce.out
机械式传送带:全程相同速度1 秒linearnone
步进式翻页书:一帧一帧地跳900 毫秒steps(6)steps(6)

一种感觉在任何速度下都保持其曲线:“400毫秒的弹力”是弹力的形状,只是更快。纯CSS中的弹簧、弹性和弹跳是从曲线采样的 linear() 列表;现成的值在 references/feels.md(“现成可用的代码”)中。弹簧“弹跳”是SwiftUI和Motion使用的0–1值(阻尼比 = 1 − 弹跳)。

如何工作

  1. 首先检查元素: 它被看到的频率,以及它是界面部分还是展示运动(下面的“选择感觉之前”)。这可能意味着更少的运动,或者没有运动。
  2. 翻译 他们的词语为感觉 + 旋钮 + 效果,使用下面“日常用语”表格。如果两三种感觉都合适,问一个简单的问题(或显示A/B切换)。
  3. 在构建之前用一行简单的话说出计划,例如“标题行在你滚动到它们时向上滑入并缓慢停止,只一次(感觉:豪华)。”他们可以在任何东西构建之前改变方向。
  4. 构建 使用持续时间、延迟和缓动作为CSS变量或一个配置对象(--motion-dur, --motion-ease, --motion-stagger),这样每次调整都是一个数字的改变。遵循“构建规则”。
  5. 报告 用平实的语言,并附上开发者的值。对于更改,展示前 → 后:“再慢一点:1.2 秒 → 1.8 秒”。保留之前的值,这样“回去”就能精确恢复它们。
  6. 保持一致性: 一旦网站的感觉明确了,建议将其保存为项目的设计标记中的运动调色板(下面),这样每个部分都以相同的方式运动。

整个网站的运动调色板

一个好的网站使用2或3种感觉,而不是14种:一种用于界面部分,一种用于展示时刻,可能一种用于强调。当有人根本无法描述运动时,用三个词询问品牌,并用一行提出一个调色板。

品牌听起来像展示界面强调
平静、值得信赖、关怀(健康、金融、法律)轻柔清爽—
高级、编辑(时尚、建筑、酒店)豪华清爽首次加载用戏剧性
大胆、快速、技术(初创公司、SaaS、体育)利落清爽弹出
友好、俏皮(儿童、食品、消费应用)弹力利落弹出或弹跳
创意、表现力(工作室、作品集、代理机构)豪华或戏剧性利落蓄力
梦幻、自然(健康、美容、冥想)循环用飘浮,内容用轻柔清爽—
复古、原始(游戏、音乐、粗野主义)步进式清爽机械式跑马灯

选择感觉之前

元素多久被看到一次?

令人愉悦一次的运动,在第十次时就会碍事。将运动量与访问者遇到元素的频率相匹配。

频率示例运动
每页每次访问导航链接、页眉、按钮、页脚链接、表单字段小而快:清爽,或者只改变颜色。键盘焦点立即显示焦点环,没有运动。这些元素的入场(例如导航在加载时滑入)仅在第一次页面浏览时播放。
每次点击页面过渡短:600毫秒或更少,即使品牌是慢而高级的
每页一次主角区、章节揭示、案例研究卡片、数字计数完整的感觉。滚动揭示只播放一次,而不是每次你往回滚动时再次播放。
每次访问一次介绍加载器、首次加载主角区时刻给戏剧性和愉悦留出空间。仅在第一次页面浏览时运行加载器。

调色板的强调放在结果上,而不是控件上:添加到购物车的按下保持快速(清爽),而购物车计数才是弹出动画。

当有人要求在一个每页元素上使用缓慢的感觉时,构建快速版本并用一句话说明如何切换:“导航链接在每个页面上,所以我保持了快速;慢速版本是一个数字的替换。”不要等待回答;这是他们的决定。

界面部分还是展示?

  • 界面部分: 访问者正试图做某事。导航下拉菜单、移动菜单、标签页、手风琴、模态框、工具提示、表单反馈、筛选器。将它们保持在 300 毫秒或更少,无论感觉如何;移动菜单和模态框可以上升到 400 毫秒。退出以大约75%的进入速度运行:将较短的持续时间放在关闭状态。
  • 展示运动: 设定氛围。主角区、章节揭示、图片揭示、跑马灯、背景循环、首次加载时刻。使用感觉本身的速度,长时间也没问题。

按元素的默认值(当没有给出感觉时)

这里的速度替换了感觉本身的速度。任何反馈(“感觉廉价”、“太弹了”)都会覆盖这些默认值。

元素感觉速度
按钮、链接、切换、悬停、工具提示清爽150 毫秒
导航下拉菜单、标签页、卡片悬停利落250 毫秒
手风琴、常见问题顺滑300 毫秒
移动菜单、模态框、抽屉、面板弹力400 毫秒
拖放弹力600 毫秒
幻灯片、轮播、在屏幕上移动的东西顺滑500 毫秒
文字和图片揭示(向上淡入24像素,交错60-80毫秒)调色板的展示感觉;如果没有提示,则利落感觉本身
页面过渡顺滑600 毫秒
主角区时刻、首次加载戏剧性1.2 秒
背景循环、环境形状飘浮2 秒
成功状态、徽章弹出450 毫秒
加载器、跑马灯、滚动擦洗运动机械式根据需要

日常用语

使用这些进行翻译。左列是人们实际说的话;都不需要运动知识。在较长的对话中,每个翻译展示一次,然后静默应用。

词语 → 感觉

他们说理解为何时询问
高级、昂贵、优雅、有档次、高端、豪华、“像一本杂志”、“缓慢而自信”豪华—
顺滑、流畅、黄油般、无缝、丝滑、“滑行”顺滑(横向移动)或轻柔(出现)元素不能明显提示时:“从头到尾均匀滑行,还是轻轻到达并渐隐至停止?”
柔和、平静、放松、安静、舒适、温暖、“不花哨”轻柔—
微妙、几乎不易察觉、“不想让人注意到”清爽(界面)或轻柔(内容)—
梦幻、轻盈、漂浮、失重、“像羽毛”、“像在水下”飘浮—
快、迅速、响应快、即时、点击强、紧凑、“像电灯开关”清爽(小东西)或利落(大东西)大小不明确
有冲击力、有活力、大胆、自信、有力、“重重落地”、“有态度”利落—
自然、有物理感、有生命力、“像手机应用”、“像真实物体”弹力—
有趣、俏皮、可爱、友好、顽皮、快乐弹出、弹力或弹性几乎总是:“跳过头一点、柔和的弹簧式稳定,还是果冻般的摇晃?”
弹跳的弹跳(落地并弹跳)或弹出/弹力(过冲后稳定)总是:“像球落地一样弹跳,还是稍微过头然后稳定?”
果冻状、摇晃的、橡胶感、有弹性、抖动弹性—
电影感、史诗、“像电影”、有力、沉重、“一个惊喜时刻”、大揭示戏剧性—
卡通、“先蓄力”、“像弹弓”蓄力—
机器人、恒定、稳定、“像传送带”、滚动条机械式—
复古、断续、定格动画、像素、故障感、“像老式电子游戏”、翻页书步进式—
现代、酷、不错、简洁、“让它出彩”、“让它好看”、“加点动画”、“让它有活力”本身没有意义总是:提供3种适合上下文的用平实语言描述的感觉,或者用三个词询问品牌(“让它出彩”可能意味着弹出感觉,或者只是“更引人注目”)

反馈 → 旋钮

他们说更改
太快、匆忙、“眨眼的功夫就错过了”、“我看不到它”速度 × 1.5
太慢、迟缓、滞后、“永远完不成”、“我在等它”速度 ÷ 1.5。在界面部分上,同时检查300毫秒的限制。
突然、刺耳、颠簸、“弹回原位”、“停止得太突然”停止:更柔和,沿着 power2.out → power3.out → power4.out → expo.out 前进一步(CSS值在 references/feels.md)
软绵绵、“结尾拖沓”、“爬行”、“需要太长时间才能稳定”停止:更坚硬(更短的尾巴),或更快
微弱、无生气、“需要更多冲击力”、“没有落地”停止更坚硬 + 速度 ÷ 1.5,或切换到利落
太弹了、“太多了”、俗气、孩子气、“过分了”超调降低一步:弹出 cubic-bezier(0.34, 1.56, 0.64, 1) → 一点点 cubic-bezier(0.34, 1.4, 0.64, 1) → 无(利落)
感觉廉价通常是运动过多:距离降低和超调降低;如果慢,则速度 ÷ 1.5
跳跃、抖动、“不知从哪里突然出现”它从无到有生长或超调:从 scale(0.95) 开始(构建规则),超调降低一步,距离降低
僵硬、机器人、死气沉沉、“需要更多生命力”超调增加一步,或切换到弹力
平淡、无聊、“什么都没发生”、“我没注意到”交错增加,或距离增加
忙碌、分散注意力、“事情太多了”、烦人强度降低,交错降低。烦人通常意味着看得太频繁:检查“元素多久被看到一次?”
“让我头晕”、“让我想吐”移除视差、大缩放和长距离移动;检查减少动画的备用方案
开始太晚/太早延迟减少/增加,以100毫秒为步长
感觉不对、“不太对”、“我不知道哪里错了”不要猜:问“是速度、开始方式、停止方式,还是结尾的小弹跳?”,或并排显示两个版本

构建规则

  • 用 transform 移动,用 opacity 淡出。 不要对 width、height、top、left 或 margin 做动画;它们在滚动时会卡顿。对于手风琴,grid-template-rows: 0fr → 1fr 是公认的例外(内容放在带有 min-height: 0; overflow: hidden 的内部包装器中)。永远不要 transition: all;命名属性。
  • 永远不要从无到有生长。 从 scale(0.95) 开始缩放进入,并带有 opacity: 0(对于更大的弹出使用0.9),永远不要用 scale(0)。
  • 根据视口裁剪而不是根据父级。 overflow: clip 是你想要的修剪图案的方式,而不是 overflow: hidden,后者设置了新的堆叠上下文并且不能与 overflow: visible 在同一轴上共存。
  • 尊重 prefers-reduced-motion。 默认是关于减速运动的,所以“减少”意味着减少不必要的运动,而不一定是消除所有运动。如果用户偏好是 reduce:
    • 移除视差效果、大缩放、长距离移动和所有背景循环。
    • 将所有持续时间和延迟减少到150毫秒以下(将任何值乘以 0.3 并向下取整)。
    • 保留出必要的界面运动:导航下拉菜单、工具提示、切换、反馈指示器仍然可以动画,但速度要快得多。
    • 对于使用GSAP的项目:在GSAP之上应用此规则,使用一个预设的“快速”覆盖。
  • 触摸设备需要更大的交互目标。 可悬停的元素在触摸上变为点击,确保所有交互式元素在触摸端有至少44×44像素的点击目标大小,并且触摸延迟(来自 fastclick 或 CSS touch-action: manipulation)已经被处理。
  • 检查时间对应的所见。 动画的视觉节奏属性应该与屏幕上发生的其他事情协调。当用户的语言设置为从右到左时,将进入方向反转,以便运动指向阅读方向。

运动审查清单

在部署之前,检查以下几点(或者与某人一起审查):

  1. 所有进入动画是否只播放一次? 标记每个部分以免再次触发滚动揭示。
  2. 每次加载是否有多于3个同时动画? 如果是,交错它们以减少视觉过载。
  3. 退出是否比进入更快? 对于界面元素,退出运行约75%的进入时间。
  4. 是否所有焦点指示器都使用焦点环,没有任何动画? 键盘用户需要即时反馈。
  5. 对于减少动画,是否有清晰、功能性的备用方案? 元素可见,布局不变。
  6. 动画是否依赖 window.innerHeight 或 window.innerWidth? 确保它们被防抖处理(~100毫秒)。
  7. 是否所有嵌套动画都使用声明的CSS变量? 没有硬编码的计时。
  8. 是否所有动画都在改变 transform 和 opacity 属性? 没有布局触发的属性。
  9. 在触控设备上,悬停触发动画是否被移除或替换? 触摸没有悬停状态。
  10. 是否所有动画都最终稳定下来? 无限循环应该在背景/装饰元素上,而不是在内容元素上。

相关技能