Skip to content

Instantly share code, notes, and snippets.

@ashrocket
Created May 18, 2026 20:21
Show Gist options
  • Select an option

  • Save ashrocket/c60b9a65718fe7e79b420ec948b5b093 to your computer and use it in GitHub Desktop.

Select an option

Save ashrocket/c60b9a65718fe7e79b420ec948b5b093 to your computer and use it in GitHub Desktop.
Lottie animation work — lessons learned (CarerCare + Pidgin)

Lottie Animation Work — Lessons Learned

What Lottie Is

Lottie is a JSON-based animation format. You describe vector animations (originally from After Effects via Bodymovin, now also from Claude, Figma, or LottieFiles) as a .json file. It plays back at any size, on web, iOS, Android, and macOS.

  • Web: lottie-web npm package or CDN. React wrapper: @lottiefiles/react-lottie-player
  • iOS/macOS: lottie-spm (Swift Package Manager) — first-class SwiftUI support via LottieView
  • Framer: Lottie JSON files drop in natively — no code required

Where Lottie Fits (and Where It Doesn't)

Context Use Lottie? Notes
Web app UI (React, Astro, vanilla) ✅ Yes Loading states, empty states, confirmations, micro-interactions
iOS/macOS SwiftUI app ✅ Yes lottie-spm is one of the most popular iOS animation libs
Phaser game canvas (in-game sprites) ❌ No Phaser owns its render pipeline — use Phaser's own animation system
Phaser game UI overlay (menus, HUD) ✅ Yes Lives in DOM above the canvas
Python backend ❌ No Backend has no UI layer

Key Design Principles

Match tone to app context

  • Caregiving app (CarerCare): Warm, slow, soft. Breathing auras, gentle checkmarks, calm completions. Not flashy.
  • Developer tool (Pidgin): Alert, purposeful, branded. Mascot-based identity animations, clear state signals.
  • Wrong: Using the same animation style for both. Tone IS part of the design.

Highest-impact moments for animation

  1. State-change confirmations — timer saved, reply sent, export complete. User took a high-stakes action; animation provides closure.
  2. Empty states — transforms "nothing here" into "ready when you are." First impression moment.
  3. Waiting states — question awaiting reply, loading. Animation communicates "something is happening."
  4. Onboarding/first launch — sets the visual identity before the user has done anything.

Animation is not decoration

Every Lottie in production should answer: what does this communicate that a static UI cannot? If you can't answer that, remove it.


Integration Patterns

React (CDN / no build step)

<script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js"></script>
function LottiePlayer({ src, loop = false, autoplay = true, onComplete }) {
  const ref = useRef(null);
  useEffect(() => {
    const anim = lottie.loadAnimation({
      container: ref.current,
      renderer: 'svg',
      loop,
      autoplay,
      path: src,
    });
    if (onComplete) anim.addEventListener('complete', onComplete);
    return () => anim.destroy();
  }, [src]);
  return <div ref={ref} />;
}

React (with build step)

npm install @lottiefiles/react-lottie-player
import { Player } from '@lottiefiles/react-lottie-player';
<Player autoplay loop src="/animations/empty-state.json" style={{ height: 80 }} />

SwiftUI (lottie-spm)

Add com.airbnb.ios:Lottie via Swift Package Manager.

import Lottie

LottieView(animation: .named("pigeon-idle"))
  .playing(loopMode: .loop)
  .frame(width: 120, height: 120)

For one-shot play with completion:

LottieView(animation: .named("checkmark"))
  .playing()
  .animationDidFinish { _ in onComplete() }

Color theming at runtime

Use LottieValueProvider to replace hardcoded colors in the JSON with app design tokens:

let colorProvider = ColorValueProvider(UIColor(named: "Moss")!.lottieColorValue)
lottieView.setValueProvider(colorProvider, keypath: AnimationKeypath(keypath: "**.Fill 1.Color"))

Generating Lottie JSON with Claude

The workflow that inspired this work (from @uiadrian on Threads):

  1. Upload SVGs to Claude
  2. Describe animation type, timing, and element movement in plain English
  3. Claude generates Lottie JSON ready to integrate

Prompt pattern:

"Generate a Lottie animation JSON for this SVG. It should [describe motion]. Duration: [Xs]. Loop: [yes/no]. Colors: [hex values]. The [element name] should [move/scale/fade] from [A] to [B] with [easing]."

Limitations:

  • Complex multi-layer rigs (mascots, characters) still benefit from a human animator or LottieFiles asset
  • Simple one-shot micro-interactions (checkmarks, sparks, pulses) Claude handles well
  • Always validate the JSON in the LottieFiles preview player before integrating

CarerCare — Planned Animations

# Animation Trigger Tone Complexity
1 Session saved checkmark Stop & Save → success Calm closure Easy
2 Empty state ambient loop Today screen, no entries Warm invitation Easy
3 Report bars grow on entry Reports tab opens Accomplishment Medium
4 Timer ambient breathing aura Timer running Sustained presence Easy–Med
5 Suggestion card spark AI card mounts "App understood you" Easy
6 Export sent card flies off Export → Send Billing confidence Medium
7 Category swatch pop Category selected Tactile confirmation Easy
8 Week total count-up Reports tab headline Achievement Easy–Med
9 Timer discard soft erase Discard pressed Intentional reset Easy
10 First-launch idle invitation Very first open Living empty state Medium

Starting with: #1 (checkmark) + #2 (empty state ambient)


Pidgin — Planned Animations

# Animation Trigger Layer Complexity
1 Reply sent — pigeon takes flight postReply success SwiftUI Medium
2 Empty inbox — pigeon perched idle Inbox empty state SwiftUI Easy–Med
3 Urgent question pulse Unread urgent question row SwiftUI Easy
4 Magic link sent — envelope opens Login submit SwiftUI Easy
5 Pull-to-refresh branded bird InboxView refresh SwiftUI Hard
6 Question waiting tick/pulse Unanswered question detail SwiftUI Easy
7 Document delivery drop DocViewer load SwiftUI Easy
8 Web UI login envelope send Web login submit Web Easy
9 Deep link badge glow Push notification tap → message SwiftUI Easy–Med

Starting with: #1 (pigeon flight) + #2 (pigeon idle) — same mascot rig, two states


Key Lesson: Mascot as Animation Foundation (Pidgin)

When an app has a brand identity tied to a character (Pidgin = pigeon), the highest-leverage move is to build one mascot rig with multiple states:

  • pigeon-idle.json — perched, breathing, eye blink loop
  • pigeon-flight.json — launches and exits frame
  • pigeon-sleeping.json — for archived/quiet state

One design asset, many moments. Cost: one good commission or careful LottieFiles search.


Useful Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment