obeskay

lottie-animator

Generates professional Lottie animations from static SVGs. Replaces After Effects for motion graphics. Use when the user asks to: animate logo, create lottie, svg animation, motion graphics, wiggle animation, bounce effect, rotate animation, pulse effect, entrance animation, loading animation, loop animation, icon animation, character animation, morphing, path drawing, trim path, walking animation, run cycle, walk cycle, frame-by-frame animation, sprite animation. Supports advanced bezier curves, shape modifiers, parenting, mattes, morphing, character rigs, and professional frame-by-frame animation techniques.

obeskay 12 Updated 5mo ago

Resources

1
GitHub

Install

npx skillscat add obeskay/lottie-animator-skill/lottie-animator

Install via the SkillsCat registry.

SKILL.md

Lottie Animator - SVG to Motion Graphics

Professional skill to create advanced Lottie animations from SVGs, eliminating the need for After Effects.

When to Activate

Activate this skill when the user requests:

  • Animate a logo, icon, or SVG graphic
  • Create motion graphics or animations
  • Generate Lottie JSON files
  • Effects: wiggle, bounce, rotate, pulse, fade, scale, morph
  • Entrance, loop, loading animations, or transitions
  • Path drawing/reveal animations (Trim Path)
  • Character animation, walking cycles
  • Shape morphing (icon transitions)
  • Replace After Effects workflow

Critical: SVG Understanding

Before animating ANY SVG, you MUST understand its path structure.

See: references/svg-path-mastery.md

SVG Path Command Quick Reference

Command Description Lottie Conversion
M x,y Move to Starting vertex
L x,y Line to Vertex with zero tangents
C cp1 cp2 end Cubic bezier Native support
Q ctrl end Quadratic bezier Convert to cubic
A rx ry ... Arc Split into cubic segments
Z Close path Set c: true

Path to Lottie Vertex Formula

For C x1,y1 x2,y2 x,y from point (px, py):
- Previous vertex outTangent: [x1-px, y1-py]
- Current vertex: [x, y]
- Current vertex inTangent: [x2-x, y2-y]

Main Workflow

Phase 1: Motion Philosophy (30 seconds)

MANDATORY before any code. Define:

  1. Brand Personality: Professional, playful, elegant, energetic
  2. Emotional Response: Trust, excitement, calm, urgency
  3. Motion Metaphor: Fluid like water, solid like rock, light like air
Example: "Fintech Logo → professional + trust → precise and controlled movement"
Example: "Music App → creative + energy → organic with rhythmic pulses"
Example: "Healthcare → calm + reliable → smooth, slow easings"

Phase 2: SVG Deep Analysis

Before animating, thoroughly analyze:

  1. Structure: Elements, groups, paths, viewBox dimensions
  2. Path Complexity: Vertex count, curve types (C, Q, A commands)
  3. Hierarchy: Primary elements vs. secondary details
  4. Animation Opportunities: Independent parts, stroke-based vs fill-based
# Analyze SVG structure
cat icon.svg | grep -E '<(path|g|rect|circle|ellipse|line|polyline)' | head -30

Key Questions:

  • Is it stroke-based? → Consider Trim Path animation
  • Multiple paths? → Consider staggered entrance
  • Complex shape? → Consider scale/rotate instead of morph
  • Icon library (Phosphor/Lucide)? → Usually clean, minimal vertices

Phase 3: Animation Strategy Selection

Strategy Best For Technique
Draw On Stroke icons, signatures Trim Path
Pop In Logos, buttons Scale + Opacity
Morph Icon transitions (hamburger→X) Path keyframes
Stagger Multiple elements Delayed start times
Character People, mascots Parenting + bone hierarchy
Loader Progress, spinners Rotation + Trim Path
Frame-by-Frame Walk/run cycles, complex characters ip/op layer switching

Pro Tip: For complex character animations (walk cycles, run cycles), use Frame-by-Frame technique instead of continuous animation. See references/professional-techniques.md

Phase 4: Create Lottie JSON

See: references/lottie-structure.md

Base Structure:

{
  "v": "5.12.1",
  "fr": 60,
  "ip": 0,
  "op": 120,
  "w": 512,
  "h": 512,
  "nm": "Animation Name",
  "ddd": 0,
  "assets": [],
  "layers": []
}

Phase 5: Apply Professional Easing

See: references/bezier-easing.md

Use Case Out Tangent In Tangent
Entrance [0.33, 0] [0.67, 1]
Exit [0.55, 0.055] [0.675, 0.19]
Loop [0.645, 0.045] [0.355, 1]
Bounce [0.34, 1.56] [0.64, 1]
Spring [0.5, 1.5] [0.5, 0.9]

Phase 6: Validate and Export

# Validate JSON structure
python3 -c "import json; json.load(open('animation.json'))"

# Preview
echo "Open in: https://lottiefiles.com/preview"

Shape Modifiers

See: references/shape-modifiers.md

Trim Path (Icon Drawing Animation)

{
  "ty": "tm",
  "s": {"a": 0, "k": 0},
  "e": {
    "a": 1,
    "k": [
      {"t": 0, "s": [0], "o": {"x": [0.33], "y": [0]}, "i": {"x": [0.67], "y": [1]}},
      {"t": 45, "s": [100]}
    ]
  },
  "o": {"a": 0, "k": 0},
  "m": 1
}

Repeater (Radial/Linear Patterns)

{
  "ty": "rp",
  "c": {"a": 0, "k": 8},
  "tr": {
    "r": {"a": 0, "k": 45},
    "so": {"a": 0, "k": 100},
    "eo": {"a": 0, "k": 30}
  }
}

Offset Path (Glow/Outline Effects)

{
  "ty": "op",
  "a": {"a": 1, "k": [{"t": 0, "s": [0]}, {"t": 30, "s": [8]}]},
  "lj": 2
}

Advanced Techniques

See: references/advanced-animation.md and references/professional-techniques.md

Frame-by-Frame Animation (Professional Technique)

The most professional technique for complex character animations. Instead of continuous animation, create multiple "poses" that appear/disappear in sequence using ip (in point) and op (out point).

{
  "layers": [
    {"nm": "Pose 1", "ip": 0, "op": 6, "shapes": [/* pose 1 */]},
    {"nm": "Pose 2", "ip": 6, "op": 12, "shapes": [/* pose 2 */]},
    {"nm": "Pose 3", "ip": 12, "op": 18, "shapes": [/* pose 3 */]}
  ]
}

Timing Formula: Total Frames = Poses × Frames_per_PoseDuration = Total Frames / FPS

When to Use:

  • Walk/run cycles (each pose is a different leg position)
  • Complex character animations with drastic shape changes
  • When morphing produces ugly results
  • Professional sprite-sheet style animations

Layer Parenting (Bone Hierarchy)

Use parent property to create hierarchies where moving one layer moves all children.

{
  "layers": [
    {"ind": 14, "nm": "Shadow", "ks": {"p": {"a": 0, "k": [340, 195, 0]}}},
    {"ind": 1, "nm": "Head", "parent": 14, "ks": {"p": {"a": 0, "k": [88, -84, 0]}}},
    {"ind": 2, "nm": "Body", "parent": 14, "ks": {"p": {"a": 0, "k": [0, -50, 0]}}}
  ]
}

Key Insight: Child positions are RELATIVE to parent. Moving Shadow moves all children with it.

Professional Parent Strategies:

  • Shadow as Parent: Move shadow → entire character moves (for walk cycles)
  • Body as Parent: Limbs and head follow body rotation
  • Joint as Parent: Upper arm controls forearm and hand rotation

Parent Chain Example:

Shadow (Parent for entire character)
├── Head (child)
├── Body (child)
├── Ear Inner (child)
├── Eye (child)
└── ... 13 total children

Path Morphing (Same Vertex Count Required)

{
  "ty": "sh",
  "ks": {
    "a": 1,
    "k": [
      {"t": 0, "s": [{"c": true, "v": [[0,0], [100,0], [100,100], [0,100]], "i": [...], "o": [...]}]},
      {"t": 30, "s": [{"c": true, "v": [[50,-20], [120,50], [50,120], [-20,50]], "i": [...], "o": [...]}]}
    ]
  }
}

Critical Rule: Both shapes MUST have identical vertex count for smooth morphing.

Track Mattes (Masking)

// Matte layer (defines visible area)
{"ind": 1, "nm": "Matte", "td": 1, "ty": 4, ...}

// Content layer (uses the matte)
{"ind": 2, "nm": "Content", "tt": 1, "ty": 4, ...}
tt Value Mode
1 Alpha Matte
2 Alpha Inverted
3 Luma Matte
4 Luma Inverted

Animation Principles Applied

1. Anticipation

"s": {"a": 1, "k": [
  {"t": 0, "s": [100, 100]},
  {"t": 8, "s": [95, 105]},    // Slight crouch
  {"t": 25, "s": [115, 90]},   // Main action
  {"t": 40, "s": [100, 100]}
]}

2. Squash & Stretch (Volume Preservation)

// X * Y should stay roughly constant
{"t": 0, "s": [100, 100]},   // 10000
{"t": 10, "s": [120, 83]},   // 9960 ≈ preserved
{"t": 20, "s": [85, 118]}    // 10030 ≈ preserved

3. Staggered Timing

{"ind": 1, "st": 0, "ip": 0},
{"ind": 2, "st": 3, "ip": 3},   // 3 frame delay
{"ind": 3, "st": 6, "ip": 6},   // 6 frame delay
{"ind": 4, "st": 9, "ip": 9}    // 9 frame delay

4. Follow-Through with Overshoot

"r": {"a": 1, "k": [
  {"t": 0, "s": [0]},
  {"t": 15, "s": [95]},    // Overshoot target
  {"t": 25, "s": [88]},    // Settle back
  {"t": 35, "s": [90]}     // Final position
]}

Common Animation Recipes

Loading Spinner

{
  "shapes": [
    {"ty": "el", "s": {"a": 0, "k": [60, 60]}},
    {"ty": "st", "w": {"a": 0, "k": 4}, "c": {"a": 0, "k": [0.2, 0.5, 1, 1]}, "lc": 2},
    {"ty": "tm", "s": {"a": 0, "k": 0}, "e": {"a": 0, "k": 75},
     "o": {"a": 1, "k": [{"t": 0, "s": [0]}, {"t": 60, "s": [360]}]}}
  ],
  "ks": {"r": {"a": 1, "k": [{"t": 0, "s": [0]}, {"t": 120, "s": [360]}]}}
}

Checkmark Draw

{
  "shapes": [
    {"ty": "sh", "ks": {"a": 0, "k": {"c": false, "v": [[20,50], [40,70], [80,30]], "i": [[0,0], [0,0], [0,0]], "o": [[0,0], [0,0], [0,0]]}}},
    {"ty": "st", "w": {"a": 0, "k": 6}, "c": {"a": 0, "k": [0.2, 0.8, 0.4, 1]}, "lc": 2, "lj": 2},
    {"ty": "tm", "e": {"a": 1, "k": [{"t": 0, "s": [0]}, {"t": 30, "s": [100]}]}}
  ]
}

Heart Beat (Organic)

"s": {"a": 1, "k": [
  {"t": 0, "s": [100, 100]},
  {"t": 8, "s": [115, 115]},    // Systole (Lub)
  {"t": 12, "s": [90, 90]},     // Diastole start (Dub)
  {"t": 18, "s": [105, 105]},   // Refill
  {"t": 45, "s": [100, 100]}    // Rest
]}

Icon Pop-In with Bounce

{
  "ks": {
    "s": {"a": 1, "k": [
      {"t": 0, "s": [0, 0], "o": {"x": [0.34], "y": [1.56]}, "i": {"x": [0.64], "y": [1]}},
      {"t": 18, "s": [110, 110], "o": {"x": [0.33], "y": [0]}, "i": {"x": [0.67], "y": [1]}},
      {"t": 30, "s": [100, 100]}
    ]},
    "o": {"a": 1, "k": [
      {"t": 0, "s": [0]},
      {"t": 12, "s": [100]}
    ]}
  }
}

Icon Library Optimization

Phosphor/Lucide Icons

  • ViewBox: Usually 256x256 (Phosphor) or 24x24 (Lucide)
  • Structure: Clean paths, minimal vertices
  • Strokes: stroke-linecap="round" for Trim Path compatibility
  • Scale: Match your canvas to viewBox for 1:1

Recommended Animation Approach

  1. Simple icons → Scale + Opacity entrance
  2. Stroke icons → Trim Path drawing
  3. Multi-part icons → Staggered entrance
  4. Toggle icons → Path morphing (if vertex counts match)

Stroke + Fill Combination (Outline Style)

For professional character animations, combine stroke (contour) + fill (color) in each shape:

{
  "ty": "gr",
  "it": [
    {"ty": "sh", "ks": {...}},
    {"ty": "st", "c": {"a": 0, "k": [0.259, 0.153, 0.141, 1]}, "w": {"a": 0, "k": 1}, "lc": 2, "lj": 2},
    {"ty": "fl", "c": {"a": 0, "k": [0.302, 0.604, 0.816, 1]}},
    {"ty": "tr", ...}
  ]
}

Stroke Properties:

Property Value Description
lc (lineCap) 1=Butt, 2=Round, 3=Square Line end style
lj (lineJoin) 1=Miter, 2=Round, 3=Bevel Corner style

Professional Color Palette Example (from Running Cat):

{
  "body_fill": [0.302, 0.604, 0.816, 1],
  "outline": [0.259, 0.153, 0.141, 1],
  "eye_white": [0.902, 0.976, 1.0, 1],
  "shadow": [0.608, 0.706, 0.878, 1]
}

Common Errors

Error Cause Solution
Non-looping Last keyframe ≠ first value Match start/end keyframe values
Stiff movement No easing curves Add bezier i/o tangents
Jerky animation Keyframes too sparse Add intermediate keyframes
Morph glitches Different vertex counts Add/remove vertices to match
Wrong rotation pivot Incorrect anchor point Set a to rotation center
Path draws wrong direction Path not reversed Use "d": 3 to reverse
Ugly character animation Trying to morph complex shapes Use frame-by-frame instead

Performance Guidelines

  1. Layers: <15 for complex animations
  2. Vertices: <20 per shape for smooth morphing
  3. Frame Rate: 30fps often sufficient, 60fps for ultra-smooth
  4. Modifiers: Avoid nested repeaters
  5. Effects: Minimize blur/shadow usage
  6. File Size: Target <50KB for icons, <200KB for complex

References

Final Checklist

  • Motion philosophy defined
  • SVG structure analyzed (path commands understood)
  • Animation strategy selected (consider frame-by-frame for characters)
  • Vertex counts verified (for morphing)
  • Anchor points set correctly (for rotation)
  • Parent hierarchy established (for characters)
  • Keyframes with professional easing
  • Animation principles applied (anticipation, follow-through)
  • Stroke + fill style applied (for outline look)
  • Seamless loop verified (if applicable)
  • JSON validated
  • Preview tested at https://lottiefiles.com/preview