swiftui-animation by jamesrochabrun/skills
npx skills add https://github.com/jamesrochabrun/skills --skill swiftui-animation提供实现高级 SwiftUI 动画和 Metal 着色器集成的专业指导。涵盖动画曲线、弹簧动画、转场、匹配几何效果、PhaseAnimator、KeyframeAnimator 以及 GPU 加速的着色器效果。
// 显式动画(推荐)
withAnimation(.spring(response: 0.4, dampingFraction: 0.75)) {
isExpanded.toggle()
}
// iOS 17+ 弹簧预设
withAnimation(.snappy) { ... } // 快速,轻微弹跳
withAnimation(.smooth) { ... } // 柔和,无弹跳
withAnimation(.bouncy) { ... } // 更多弹跳
// 基础
.transition(.opacity)
.transition(.scale)
.transition(.slide)
.transition(.move(edge: .bottom))
// 组合
.transition(.move(edge: .trailing).combined(with: .opacity))
// 非对称
.transition(.asymmetric(
insertion: .move(edge: .bottom),
removal: .opacity
))
@Namespace var namespace
// 源视图
ThumbnailView()
.matchedGeometryEffect(id: "hero", in: namespace)
// 目标视图
DetailView()
.matchedGeometryEffect(id: "hero", in: namespace)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
// 颜色处理
.colorEffect(ShaderLibrary.invert())
// 像素位移
.distortionEffect(
ShaderLibrary.wave(.float(time)),
maxSampleOffset: CGSize(width: 20, height: 20)
)
// 完整图层访问
.layerEffect(ShaderLibrary.blur(.float(radius)), maxSampleOffset: .zero)
详细文档位于 references/ 目录中:
motion-guidelines.md - HIG 动效设计原则
animations.md - 完整的动画 API 指南
transitions.md - 视图转场指南
metal-shaders.md - GPU 着色器集成
struct ExpandableCard: View {
@State private var isExpanded = false
var body: some View {
VStack {
RoundedRectangle(cornerRadius: isExpanded ? 20 : 12)
.fill(.blue)
.frame(
width: isExpanded ? 300 : 150,
height: isExpanded ? 400 : 100
)
}
.onTapGesture {
withAnimation(.spring(response: 0.35, dampingFraction: 0.75)) {
isExpanded.toggle()
}
}
}
}
ForEach(Array(items.enumerated()), id: \.element.id) { index, item in
ItemRow(item: item)
.transition(.asymmetric(
insertion: .move(edge: .trailing).combined(with: .opacity),
removal: .move(edge: .leading).combined(with: .opacity)
))
.animation(.spring().delay(Double(index) * 0.05), value: items)
}
Circle()
.fill(.blue)
.frame(width: 20, height: 20)
.scaleEffect(isPulsing ? 1.2 : 1.0)
.opacity(isPulsing ? 0.6 : 1.0)
.onAppear {
withAnimation(.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) {
isPulsing = true
}
}
withAnimation 而非 .animation() 修饰符.spring(response: 0.35, dampingFraction: 0.8) 开始 - 适用于大多数交互的良好默认值withAnimation 中withAnimationzIndex 以确保正确的层级.metal 文件已添加到目标中maxSampleOffset每周安装量
380
代码仓库
GitHub 星标数
101
首次出现
Jan 21, 2026
安全审计
安装于
codex326
gemini-cli320
opencode318
github-copilot293
claude-code262
amp247
Expert guidance for implementing advanced SwiftUI animations and Metal shader integration. Covers animation curves, springs, transitions, matched geometry effects, PhaseAnimator, KeyframeAnimator, and GPU-accelerated shader effects.
// Explicit animation (preferred)
withAnimation(.spring(response: 0.4, dampingFraction: 0.75)) {
isExpanded.toggle()
}
// iOS 17+ spring presets
withAnimation(.snappy) { ... } // Fast, small bounce
withAnimation(.smooth) { ... } // Gentle, no bounce
withAnimation(.bouncy) { ... } // More bounce
// Basic
.transition(.opacity)
.transition(.scale)
.transition(.slide)
.transition(.move(edge: .bottom))
// Combined
.transition(.move(edge: .trailing).combined(with: .opacity))
// Asymmetric
.transition(.asymmetric(
insertion: .move(edge: .bottom),
removal: .opacity
))
@Namespace var namespace
// Source view
ThumbnailView()
.matchedGeometryEffect(id: "hero", in: namespace)
// Destination view
DetailView()
.matchedGeometryEffect(id: "hero", in: namespace)
// Color manipulation
.colorEffect(ShaderLibrary.invert())
// Pixel displacement
.distortionEffect(
ShaderLibrary.wave(.float(time)),
maxSampleOffset: CGSize(width: 20, height: 20)
)
// Full layer access
.layerEffect(ShaderLibrary.blur(.float(radius)), maxSampleOffset: .zero)
Detailed documentation is available in references/:
motion-guidelines.md - HIG Motion design principles
animations.md - Complete animation API guide
transitions.md - View transition guide
metal-shaders.md - GPU shader integration
struct ExpandableCard: View {
@State private var isExpanded = false
var body: some View {
VStack {
RoundedRectangle(cornerRadius: isExpanded ? 20 : 12)
.fill(.blue)
.frame(
width: isExpanded ? 300 : 150,
height: isExpanded ? 400 : 100
)
}
.onTapGesture {
withAnimation(.spring(response: 0.35, dampingFraction: 0.75)) {
isExpanded.toggle()
}
}
}
}
ForEach(Array(items.enumerated()), id: \.element.id) { index, item in
ItemRow(item: item)
.transition(.asymmetric(
insertion: .move(edge: .trailing).combined(with: .opacity),
removal: .move(edge: .leading).combined(with: .opacity)
))
.animation(.spring().delay(Double(index) * 0.05), value: items)
}
Circle()
.fill(.blue)
.frame(width: 20, height: 20)
.scaleEffect(isPulsing ? 1.2 : 1.0)
.opacity(isPulsing ? 0.6 : 1.0)
.onAppear {
withAnimation(.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) {
isPulsing = true
}
}
withAnimation over .animation() modifier for clarity.spring(response: 0.35, dampingFraction: 0.8) - Good default for most interactionswithAnimationwithAnimation when togglingzIndex for proper layering.metal file is added to targetmaxSampleOffset is set correctly for distortion effectsWeekly Installs
380
Repository
GitHub Stars
101
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex326
gemini-cli320
opencode318
github-copilot293
claude-code262
amp247
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
106,200 周安装