mcpField
E
emilkowal-animations-swift

emilkowal-animations-swift

github.com/pluk-incDesign & UI38 installs
Repository

About emilkowal-animations-swift

A reference skill for SwiftUI and AppKit animation code, with 86 rules across 10 categories for Apple platform interfaces. It provides review guidance, implementation values, and web-to-SwiftUI concept mappings.

Key features

  1. 0186 rules across 10 categories
  2. 02Review checklist for animation code
  3. 03Guidance on timing and easing
  4. 04Gesture, transition, and scroll patterns
  5. 05Accessibility and performance guidance
  6. 06Web-to-SwiftUI concept mappings

Use cases

  1. 01Reviewing SwiftUI animation implementations
  2. 02Choosing timings for interface transitions
  3. 03Building gesture-driven motion and navigation
  4. 04Checking animation accessibility and performance

Install

Copy the command and run it in a terminal.

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

After installing, type/emilkowal-animations-swiftin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with 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

Details

From the project README

SwiftUI & AppKit Animation Best Practices

Comprehensive animation guide for Apple platform interfaces, adapted from Emil Kowalski's web animation principles and Framer Motion best practices. Contains 86 rules across 10 categories targeting iOS 17+, prioritized by impact.

Review Format (Required)

When reviewing UI animation code, you MUST use a markdown table with Before/After/Why columns. Do NOT use a list with "Before:" and "After:" on separate lines. Always output an actual markdown table like this:

BeforeAfterWhy
.animation(.default).animation(.easeOut(duration: 0.2))Specify explicit easing; avoid default
scaleEffect(0)scaleEffect(0.95) with .opacity(0)Nothing in the real world appears from nothing
.easeIn on dropdown.easeOut(duration: 0.2)easeIn feels sluggish; easeOut gives instant feedback
No press feedback on buttonscaleEffect(isPressed ? 0.97 : 1.0)Buttons must feel responsive to press
.scaleEffect(anchor: .center) on popover.scaleEffect(anchor: .top) matching triggerPopovers should scale from their trigger, not center

One row per issue found. The "Why" column briefly explains the reasoning.

Review Checklist

When reviewing SwiftUI animation code, check for these issues:

IssueFix
.animation(.default) or no explicit curveSpecify exact easing: .easeOut(duration: 0.2) or .spring(duration: 0.3)
scaleEffect(0) entry animationStart from scaleEffect(0.95) with .opacity(0)
.easeIn on entering UI elementSwitch to .easeOut or .spring()
.scaleEffect(anchor: .center) on popoverSet anchor to match trigger location (modals are exempt)
Animation on keyboard-initiated actionRemove animation entirely — use instant state change
Duration > 300ms on UI elementReduce to 150-250ms or use spring
Hover animation without #if os(macOS) guardGate behind platform check or .onHover availability
withAnimation wrapping high-frequency actionRemove — actions triggered 100+/day should be instant
Animating .frame() or .padding()Use .scaleEffect, .offset, .opacity instead (GPU-accelerated)
Same enter/exit transition speedMake exit faster: .asymmetric(insertion: 0.3s, removal: 0.15s)
Elements all appear at onceAdd stagger delay (30-80ms between items)
Manual Timer/CADisplayLink animation loopUse .animation() or withAnimation (runs on render server)
Missing accessibilityReduceMotion checkAdd @Environment(\.accessibilityReduceMotion) guard
No press feedback on tappable elementAdd scaleEffect(0.97) on press via ButtonStyle

When to Apply

Reference these guidelines when:

  • Adding animations to SwiftUI views
  • Choosing easing curves, springs, or timing values
  • Implementing gesture-based interactions (drag, tap, long press)
  • Building transitions and navigation animations
  • Using matchedGeometryEffect for shared element transitions
  • Creating scroll-linked or parallax effects
  • Using iOS 17+ PhaseAnimator or KeyframeAnimator
  • Optimizing animation performance
  • Ensuring animation accessibility with accessibilityReduceMotion
  • Writing AppKit/macOS-specific animations

Rule Categories by Priority

PriorityCategoryImpactPrefix
1Timing Curves & EasingCRITICALease-
2Duration & TimingCRITICALtiming-
3Animation PropertiesHIGHprops-
4Transforms & EffectsHIGHtransform-
5Gesture & InteractionHIGHgesture-
6Transitions & NavigationMEDIUM-HIGHtransition-
7Scroll & ParallaxMEDIUMscroll-
8Strategic AnimationMEDIUMstrategy-
9Accessibility & PolishMEDIUMpolish-
10AppKit SpecificLOW-MEDIUMappkit-

Quick Reference

1. Timing Curves & Easing (CRITICAL)
2. Duration & Timing (CRITICAL)
3. Animation Properties (HIGH)
4. Transforms & Effects (HIGH)
5. Gesture & Interaction (HIGH)
6. Transitions & Navigation (MEDIUM-HIGH)
7. Scroll & Parallax (MEDIUM)
8. Strategic Animation (MEDIUM)
9. Accessibility & Polish (MEDIUM)
10. AppKit Specific (LOW-MEDIUM)

Key Values Reference

ValueUsage
.spring(duration: 0.3, bounce: 0.2)Standard iOS 17 spring animation
.spring(response: 0.3, dampingFraction: 0.7)Classic spring configuration
.easeOut(duration: 0.2)Standard UI transition
scaleEffect(0.97)Button press feedback
scaleEffect(0.95)Minimum enter scale (never scale to 0)
0.2 secondsDefault micro-interaction duration
0.3 secondsMaximum duration for UI animations
0.5 secondsSheet/drawer animation duration

Concept Mapping (Web to SwiftUI)

Web ConceptSwiftUI Equivalent
ease-out.easeOut or 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 {} / gesture modifiers
dragConstraintsDragGesture with onChange bounds
prefers-reduced-motion@Environment(\.accessibilityReduceMotion)

Reference Files

FileDescription
references/_sections.mdCategory definitions and ordering
assets/templates/_template.mdTemplate for new rules
metadata.jsonVersion and reference information

Comments

Markdown supported