Create animated logo files (Lottie JSON, GIF, MP4) from static logo images. This skill should be used when users provide a logo image (PNG/SVG/JPG) and request any kind of logo animation, motion graphics, animated logo effect, waveform animation, bouncing logo, rotating logo, pulsing logo, wiggling logo, or ask to "animate my logo" or "make my logo move". Outputs standalone animation files (not React/HTML artifacts). Generates Lottie JSON with automatic GIF/MP4 rendering, perfect loop validation, and professional motion design patterns.
Create professional logo animations using Lottie JSON format. Ingest existing logos (PNG/SVG/JPG) or generate simple text-based logos, then animate them with professionally-crafted motion patterns. Output includes Lottie JSON with automatic GIF preview rendering and optional MP4 export.
Trigger this skill when users request:
Important: This skill outputs standalone animation files (Lottie JSON, GIF, MP4), NOT interactive React/HTML artifacts. If user wants an interactive tool or web component, defer to artifacts-builder skill.
Before creating any animation, answer these three questions:
What personality does this brand have? (playful, professional, bold, elegant, innovative, trustworthy)
What emotion should the animation evoke? (excitement, trust, creativity, confidence, curiosity)
What motion metaphor fits? (organic growth, mechanical precision, energetic burst, elegant reveal, rhythmic pulse)
Example: "Canva = Creative tool brand → Playful energy + organic growth → Simultaneous entrance with pulse"
See Animation Philosophy section below for detailed framework.
Before creating animation, understand what you're working with:
# For SVG logos - identify elements
python scripts/extract_svg_elements.py logo.svg --list
Quick decision tree:
Logo has text?
├─ YES → Read references/text_animation_guide.md FIRST
└─ NO → Continue with standard workflow
Multiple elements (icon + text)?
├─ YES → Extract separately, decide timing (simultaneous vs staggered)
└─ NO → Animate as single unit
SVG or PNG?
├─ SVG → Can extract elements cleanly
└─ PNG → Limited to single-logo animations
# Single logo (simple animation)
python scripts/prepare_logo.py logo.png --max-size 500 --optimize
# Creates: logo_optimized.png (30-50KB) + logo_base64.txt
# Multi-element logo (extract FIRST, then convert)
python scripts/extract_svg_elements.py logo.svg --output-dir ./elements/
python scripts/prepare_logo.py elements/icon.svg --max-size 200
python scripts/prepare_logo.py elements/text.svg --max-size 250
Size guidelines:
Use EXTERNAL references during development:
{
"v": "5.7.4",
"fr": 60,
"ip": 0,
"op": 180,
"w": 800,
"h": 800,
"layers": [{
"ind": 1,
"ty": 2,
"nm": "Logo",
"refId": "logo_image",
"ks": {
"o": {
"a": 1,
"k": [
{"t": 0, "s": [0], "e": [100], "i": {"x": [0.42], "y": [1]}, "o": {"x": [0.58], "y": [0]}},
{"t": 60, "s": [100]}
]
}
}
}],
"assets": [{"id": "logo_image", "w": 512, "h": 512, "p": "logo_optimized.png", "e": 0}]
}
Critical: Use "e": 0 (external reference) during development to avoid Cairo memory errors.
See Animation Patterns below for common effects, or references/detailed_examples.md for full code examples.
# Check Lottie structure (warns about large embedded assets)
python scripts/validate_lottie.py logo_animation.json
# Check loop quality (if creating looping animation)
python scripts/validate_loop.py logo_animation.json
# RECOMMENDED: Preview first (renders only first N frames) - saves time!
python scripts/render_lottie.py logo_animation.json preview.gif --preview-frames 60
# Alternative: Test render mode (200x200, 15fps with confirmation prompt)
python scripts/render_lottie.py logo_animation.json logo.gif --test-render
# If preview looks good → Render full animation
python scripts/render_lottie.py logo_animation.json logo.gif
# Optional: MP4 export (better compression than GIF)
python scripts/render_lottie.py logo_animation.json logo.mp4
# Optional: Batch export all formats
python scripts/batch_export.py logo_animation.json ./output gif,mp4,json
Important notes:
--preview-frames N to render only first N frames for quick validationAfter successful rendering, optionally convert to embedded base64 for standalone distribution:
// Replace external reference with base64 from logo_base64.txt
"assets": [{"id": "logo_image", "p": "data:image/png;base64,...", "e": 1}]
Note: Keep external version for future edits/rendering!
Phase 1: Define Philosophy (think before implementing)
Phase 2: Express Through Technical Choices
"Confident Professionalism"
"Playful Energy"
"Audio/Speech Brand"
More examples in references/preset_library.md and references/animation_theory.md.
Choose motion type based on brand personality:
Professional brands (B2B, finance, legal)
Parameters:
0.42/0.58 (standard ease-in-out)Use for: Corporate logos, B2B brands, professional presentations
Audio, music, speech AI, nature brands
Parameters:
0.25/0.75 (softer, more organic)Use for: Audio apps, music platforms, speech AI, organic products
Example: Vertical bar waveform pattern in references/detailed_examples.md
Startups, social media, marketing
Parameters:
0.34/1.56 (playful bounce) or 0.6/-0.28 (back overshoot)Use for: Startup logos, social media intros, marketing campaigns
Premium brands, film production
Parameters:
Use for: Luxury brands, film intros, high-end agency work
| Pattern | Duration | Properties | Use Case |
|---|---|---|---|
| Fade + Gentle Scale | 1.5s | Opacity: 0→100%, Scale: 95→100% | Corporate entrances |
| Bounce Entrance | 1.2s | Position, Scale, Opacity | Energetic brands |
| Scale Pulse | 3s loop | Scale: 100→103→100% | Idle states, CTAs |
| Smooth Rotation | 10s loop | Rotation: 0→360° | Loading, tech logos |
| Wiggle/Jello | 0.8s | Rotation: ±5° oscillation | Playful notifications |
Full code examples: references/detailed_examples.md
Pattern 1: Simultaneous Entrance Both elements appear together (cohesive brand)
Icon: {"t": 0, "s": [0]}, {"t": 60, "s": [100]}
Text: {"t": 0, "s": [0]}, {"t": 60, "s": [100]}
// Both start at t:0 → Synchronized
Pattern 2: Staggered Entrance Icon establishes first, text reinforces (storytelling)
Icon: {"t": 0, "s": [0]}, {"t": 45, "s": [100]}
Text: {"t": 30, "s": [0]}, {"t": 75, "s": [100]}
// Text delayed 30 frames (0.5s at 60fps)
Timing guidelines:
Full patterns: references/detailed_examples.md#multi-element-coordination
Always classify user intent to select appropriate animation style:
| Intent | Keyframes | Easing | FPS | Duration | Motion |
|---|---|---|---|---|---|
| Subtle/Professional | 8-12 | 0.42/0.58 | 30 | 1.5-2s | Slow, controlled, minimal rotation |
| Bold/Attention | 15-25 | 0.34/1.56 | 60 | 0.8-1.5s | Medium-fast, dynamic, ±10-20% scale |
| Playful/Creative | 12-20 | 0.34/1.56 | 30-60 | 1-2s | Bouncy, exaggerated, wiggle effects |
| Organic/Continuous | 25-45 | 0.25/0.75 | 60 | 3s | Waveforms, pulses, flowing rhythms |
Default: Provide animation rather than asking questions, unless user explicitly requests options.
Current behavior:
Example:
project/
├── animations/
│ └── logo_animation.json (references "logo_optimized.png")
└── logo_optimized.png
# This will FAIL - asset not found
Solution: Place assets in the same directory as the JSON file:
project/animations/
├── logo_animation.json
└── logo_optimized.png # ✅ Correct location
Embedded base64 ("e": 1):
External references ("e": 0):
Recommended workflow:
Full list with code examples: references/anti_patterns.md
If logo contains text, you MUST follow specialized workflow:
See: references/text_animation_guide.md for complete guide
Always use external file references during development/rendering:
// ✅ CORRECT: External reference
"assets": [{"id": "logo", "p": "logo_optimized.png", "e": 0}]
// ❌ WRONG: Embedded base64 (causes Cairo crash if >100KB)
"assets": [{"id": "logo", "p": "data:image/png;base64,...", "e": 1}]
Why: Cairo renderer crashes with embedded images >100KB. Use external during development, optionally embed AFTER successful rendering.
| Script | Purpose | Example |
|---|---|---|
prepare_logo.py | Optimize and convert logo images | python scripts/prepare_logo.py logo.png --max-size 500 |
extract_svg_elements.py | Extract elements from SVG | python scripts/extract_svg_elements.py logo.svg --list |
validate_lottie.py | Check Lottie structure | python scripts/validate_lottie.py animation.json |
validate_loop.py | Verify perfect loop | python scripts/validate_loop.py animation.json |
render_lottie.py | Render to GIF/MP4 (with asset validation) | python scripts/render_lottie.py animation.json output.gif |
render_lottie.py --preview-frames N | Quick preview (first N frames) | python scripts/render_lottie.py animation.json preview.gif --preview-frames 60 |
render_lottie.py --test-render | Test mode with size warnings | python scripts/render_lottie.py animation.json test.gif --test-render |
batch_export.py | Export multiple formats | python scripts/batch_export.py animation.json ./output gif,mp4 |
New features in render_lottie.py:
--preview-frames N) - renders only first N frames--test-render) - small test render with confirmation promptDetailed usage: references/script_usage.md
{
"v": "5.7.4", // Lottie version
"fr": 60, // Frame rate
"ip": 0, // In point (start frame)
"op": 180, // Out point (end frame)
"w": 800, // Width
"h": 800, // Height
"layers": [...], // Animation layers
"assets": [...] // Image/asset references
}
o: Opacity (0-100)p: Position [x, y]s: Scale [x%, y%]r: Rotation (degrees)a: Anchor point [x, y]"o": {
"a": 1, // Animated (1) or static (0)
"k": [
{"t": 0, "s": [0], "e": [100], "i": {...}, "o": {...}},
{"t": 60, "s": [100]}
]
}
t: Time (frame number)s: Start valuee: End valuei: In tangent (ease in)o: Out tangent (ease out)Complete specification: references/lottie_spec.md
Never use linear easing - always use curves for professional motion.
| Easing | Values | Feel | Use Case |
|---|---|---|---|
| Ease-in-out (standard) | 0.42/0.58 | Balanced, professional | Corporate, general use |
| Organic | 0.25/0.75 | Soft, natural | Audio brands, waveforms, continuous motion |
| Bounce | 0.34/1.56 | Playful, energetic | Startups, playful brands |
| Back | 0.6/-0.28 & 0.735/0.045 | Overshoot, dynamic | Bold marketing, attention-grabbing |
Theory and examples: references/animation_theory.md
pip install lottie[all] # Lottie manipulation
pip install Pillow # Image processing
pip install pycairo # Cairo rendering (for GIF)
macOS:
brew install cairo pkg-config
pip install pycairo
Linux (Ubuntu/Debian):
sudo apt-get install libcairo2-dev pkg-config python3-dev
pip install pycairo
Verify:
python3 -c "import cairo; print('Cairo OK')"
Troubleshooting: references/troubleshooting.md#cairo-and-dependencies
Asset not found errors:
render_lottie.py - it validates assets before renderingBlank/corrupted output:
MemoryError during GIF rendering:
"e": 0) insteadLoop has visible jump:
validate_loop.py and ensure last frame = first frameText looks wrong:
extract_svg_elements.pyAnimation too choppy:
Preview renders save time:
--preview-frames 60 to validate concept before full render--test-render for interactive testing with size warningsComprehensive guide: references/troubleshooting.md
Target sizes for different use cases:
| Use Case | Lottie JSON | GIF | MP4 | Image Assets |
|---|---|---|---|---|
| Email signature | 20-50KB | 500KB-1MB | 200-500KB | <30KB each |
| Website hero | 30-80KB | 1-3MB | 500KB-1.5MB | <50KB each |
| Social media | 50-150KB | 3-8MB | 1-3MB | <80KB each |
| Splash screen | 30-100KB | 2-5MB | 800KB-2MB | <60KB each |
Optimization: Use scripts/optimize_lottie.py to reduce file sizes by removing redundant keyframes and rounding values.
Quick reference to common presets (full code in references/preset_library.md):
Branding Styles:
Use Cases:
Real-World Examples: Study hover animations from major brands in references/real-world-examples/:
Before creating animation, verify:
"e": 0) during developmentvalidate_loop.py if creating loopIf all checked → Proceed with confidence ✅
validate_loop.py to verifyvalidate_lottie.py and validate_loop.pyRemember: The goal is creating motion that enhances brand identity, not random animation. Philosophy-first workflow ensures alignment from the start.