mcpField
E
emilkowal-animations-swift

emilkowal-animations-swift

github.com/pluk-inc设计与 UI38 次安装
代码仓库

关于 emilkowal-animations-swift

面向 Apple 平台界面的 SwiftUI 和 AppKit 动画参考技能,包含分为 10 类的 86 条规则。它提供代码评审指南、实现参数参考,以及 Web 概念到 SwiftUI 的映射。

主要功能

  1. 01涵盖 10 类的 86 条规则
  2. 02动画代码评审清单
  3. 03时长与缓动曲线指南
  4. 04手势、转场和滚动模式
  5. 05无障碍与性能建议
  6. 06Web 到 SwiftUI 的概念映射

适用场景

  1. 01评审 SwiftUI 动画实现
  2. 02为界面转场选择时长
  3. 03构建手势驱动的动效与导航
  4. 04检查动画的无障碍性和性能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pluk-inc/skills --skill emilkowal-animations-swift

安装后在 Claude Code 中输入/emilkowal-animations-swift确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

metadata.json
assets/templates/
_template.md
references/
_sections.md
appkit-animator-proxy.md
appkit-core-animation.md
appkit-implicit-animations.md
appkit-layer-backed-views.md
appkit-nsanimation-context.md
appkit-spring-animation.md
ease-avoid-linear.md
ease-custom-timing-curve.md
ease-ease-in-for-exits.md
ease-ease-inout-for-emphasis.md
ease-match-context.md
ease-prefer-easeout.md
ease-spring-damping.md
ease-spring-default.md
ease-spring-ios17.md
ease-spring-response.md
gesture-asymmetric-press-release.md
gesture-cancellation.md
gesture-drag-basic.md
gesture-drag-constraints.md
gesture-drag-velocity.md
gesture-gesture-state.md
gesture-hover-macos.md
gesture-long-press.md
gesture-magnify-gesture.md
gesture-rotation-gesture.md
gesture-sensory-feedback.md

详细介绍

SwiftUI 与 AppKit 动画最佳实践

面向 Apple 平台界面的全面动画指南,改编自 Emil Kowalski 的 Web 动画原则和 Framer Motion 最佳实践。包含 10 个类别中的 86 条规则,针对 iOS 17+,并按影响程度排序。

审查格式(必需)

审查 UI 动画代码时,必须使用包含“修改前/修改后/原因”列的 Markdown 表格。不要使用将“修改前:”和“修改后:”分成多行的列表。始终输出如下所示的实际 Markdown 表格:

修改前修改后原因
.animation(.default).animation(.easeOut(duration: 0.2))明确指定缓动曲线;避免使用默认值
scaleEffect(0)scaleEffect(0.95) with .opacity(0)现实世界中没有东西会凭空出现
.easeIn on dropdown.easeOut(duration: 0.2)easeIn 显得迟缓;easeOut 能提供即时反馈
No press feedback on buttonscaleEffect(isPressed ? 0.97 : 1.0)按钮必须能对按压操作做出响应
.scaleEffect(anchor: .center) on popover.scaleEffect(anchor: .top) matching trigger弹出框应从触发位置缩放,而不是从中心缩放

每个发现的问题占一行。“原因”列简要说明理由。

审查清单

审查 SwiftUI 动画代码时,请检查以下问题:

问题修复方法
.animation(.default) 或未明确指定曲线指定精确的缓动方式:.easeOut(duration: 0.2) 或 .spring(duration: 0.3)
使用 scaleEffect(0) 的入场动画从 scaleEffect(0.95) 开始,并添加 .opacity(0)
进入 UI 元素时使用 .easeIn改用 .easeOut 或 .spring()
弹出框使用 .scaleEffect(anchor: .center)将锚点设为与触发位置一致(模态框除外)
由键盘触发的操作使用动画完全移除动画——改用即时状态变化
UI 元素的动画时长 > 300ms缩短至 150-250ms,或使用 spring
悬停动画没有 #if os(macOS) 保护添加平台检查,或检查 .onHover 是否可用
withAnimation 包裹高频操作移除——每天触发 100 次以上的操作应即时响应
对 .frame() 或 .padding() 添加动画改用 .scaleEffect、.offset、.opacity(由 GPU 加速)
入场和退出使用相同的转场速度加快退出速度:.asymmetric(insertion: 0.3s, removal: 0.15s)
所有元素同时出现添加错开延迟(项目之间间隔 30-80ms)
使用手动 Timer/CADisplayLink 动画循环改用 .animation() 或 withAnimation(在渲染服务器上运行)
未检查 accessibilityReduceMotion添加 @Environment(\.accessibilityReduceMotion) 检查
可点击元素没有按压反馈通过 ButtonStyle 在按压时添加 scaleEffect(0.97)

适用场景

在以下情况中参考这些指南:

  • 为 SwiftUI 视图添加动画
  • 选择缓动曲线、弹簧效果或时间参数
  • 实现基于手势的交互(拖动、轻点、长按)
  • 构建转场和导航动画
  • 使用 matchedGeometryEffect 实现共享元素转场
  • 创建与滚动联动的效果或视差效果
  • 使用 iOS 17+ 的 PhaseAnimator 或 KeyframeAnimator
  • 优化动画性能
  • 通过 accessibilityReduceMotion 确保动画的无障碍支持
  • 编写 AppKit/macOS 专用动画

按优先级划分的规则类别

优先级类别影响前缀
1时间曲线与缓动严重ease-
2时长与时间严重timing-
3动画属性高props-
4变换与效果高transform-
5手势与交互高gesture-
6转场与导航中高transition-
7滚动与视差中scroll-
8策略性动画中strategy-
9无障碍与润色中polish-
10AppKit 专用低至中appkit-

快速参考

1. 时间曲线与缓动(关键)
2. 持续时间与时序(关键)
3. 动画属性(高优先级)
4. 变换与效果(高优先级)
5. 手势与交互(高)
6. 转场与导航(中高)
7. 滚动与视差(中)
8. 策略性动画(中)
9. 无障碍与润色(中)
10. AppKit 特定内容(低至中)

关键值参考

值用法
.spring(duration: 0.3, bounce: 0.2)标准 iOS 17 弹簧动画
.spring(response: 0.3, dampingFraction: 0.7)经典弹簧配置
.easeOut(duration: 0.2)标准 UI 转场
scaleEffect(0.97)按钮按下反馈
scaleEffect(0.95)最小进入缩放值(绝不缩放至 0)
0.2 秒默认微交互时长
0.3 秒UI 动画的最长时长
0.5 秒Sheet/抽屉动画时长

概念映射(Web 到 SwiftUI)

Web 概念SwiftUI 对应项
ease-out.easeOut 或 Animation.easeOut(duration:)
cubic-bezier(a,b,c,d).timingCurve(a, b, c, d, duration:)
Framer Motion spring.spring(duration:bounce:)(iOS 17+)
transform: scale(0.97).scaleEffect(0.97)
transform-origin.scaleEffect(anchor: .topLeading)
useMotionValue@State / @GestureState
AnimatePresence.transition() + .id()
layoutId.matchedGeometryEffect(id:in:)
useScrollGeometryReader + PreferenceKey
whileHover/whileTap.onHover {} / 手势修饰符
dragConstraints使用 onChange 边界的 DragGesture
prefers-reduced-motion@Environment(\.accessibilityReduceMotion)

参考文件

文件描述
references/_sections.md分类定义和排序
assets/templates/_template.md新规则模板
metadata.json版本和参考信息

评论

支持 Markdown