Claude-skill-registry-data lottie
Renders After Effects animations as lightweight JSON on web and mobile using lottie-web. Use when adding vector animations, loading indicators, or complex motion graphics without video files.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry-data
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/lottie" ~/.claude/skills/majiayu000-claude-skill-registry-data-lottie && rm -rf "$T"
manifest:
data/lottie/SKILL.mdsource content
Lottie Web Animation
Render After Effects animations natively with lightweight JSON. Vector-based, scalable, and performant.
Quick Start
npm install lottie-web
import lottie from 'lottie-web'; const animation = lottie.loadAnimation({ container: document.getElementById('lottie-container'), renderer: 'svg', loop: true, autoplay: true, path: '/animations/loading.json' // or animationData: jsonObject });
loadAnimation Options
const animation = lottie.loadAnimation({ // Required container: document.getElementById('container'), // DOM element // Animation source (use one) path: '/animation.json', // URL to JSON file animationData: importedJSON, // or imported JSON object // Renderer renderer: 'svg', // 'svg' | 'canvas' | 'html' // Playback loop: true, // boolean or number of loops autoplay: true, // start immediately name: 'myAnimation', // reference name // Performance rendererSettings: { preserveAspectRatio: 'xMidYMid slice', progressiveLoad: true, // improve initial load hideOnTransparent: true, // hide elements with 0 opacity className: 'lottie-svg' // class for SVG element } });
Animation Control Methods
// Playback animation.play(); animation.pause(); animation.stop(); // stop and go to first frame // Speed & Direction animation.setSpeed(2); // 2x speed animation.setSpeed(0.5); // half speed animation.setDirection(1); // forward animation.setDirection(-1); // reverse // Seek animation.goToAndPlay(30, true); // frame 30, play animation.goToAndStop(2, false); // 2 seconds, stop // Second param: true = frames, false = seconds // Segments animation.playSegments([0, 30], true); // play frames 0-30 animation.playSegments([[0, 10], [20, 30]], false); // multiple segments // Info animation.getDuration(); // in seconds animation.getDuration(true); // in frames animation.totalFrames; animation.currentFrame; animation.isPaused; // Cleanup animation.destroy();
Events
// Event listener style animation.addEventListener('complete', () => { console.log('Animation completed'); }); animation.addEventListener('loopComplete', () => { console.log('Loop finished'); }); animation.addEventListener('enterFrame', (e) => { console.log('Current frame:', e.currentTime); }); // All events 'complete' // non-looping animation finished 'loopComplete' // loop cycle finished 'enterFrame' // each frame (use sparingly) 'segmentStart' // segment started playing 'config_ready' // initial config loaded 'data_ready' // animation data loaded 'data_failed' // failed to load data 'DOMLoaded' // elements added to DOM 'destroy' // animation destroyed
Global Lottie Methods
import lottie from 'lottie-web'; // Control all animations lottie.play(); // play all lottie.play('myAnimation'); // play by name lottie.stop(); lottie.pause(); // Settings lottie.setSpeed(1.5); // all animations lottie.setDirection(-1); // State lottie.freeze(); // suspend all animations lottie.unfreeze(); // resume // Responsive lottie.resize(); // recalculate sizes // Quality (canvas renderer) lottie.setQuality('high'); // 'high' | 'medium' | 'low' lottie.setQuality(2); // or number (1-10) // Auto-discover lottie.searchAnimations(); // find elements with class "lottie" // Cleanup lottie.destroy('myAnimation'); // by name lottie.destroy(); // all
React Integration
Using lottie-react
npm install lottie-react
import Lottie from 'lottie-react'; import animationData from './animation.json'; function MyAnimation() { return ( <Lottie animationData={animationData} loop={true} autoplay={true} style={{ width: 300, height: 300 }} /> ); }
With Ref Control
import { useRef } from 'react'; import Lottie from 'lottie-react'; import animationData from './animation.json'; function ControlledAnimation() { const lottieRef = useRef(); const handlePlay = () => lottieRef.current?.play(); const handlePause = () => lottieRef.current?.pause(); const handleStop = () => lottieRef.current?.stop(); return ( <> <Lottie lottieRef={lottieRef} animationData={animationData} autoplay={false} /> <button onClick={handlePlay}>Play</button> <button onClick={handlePause}>Pause</button> <button onClick={handleStop}>Stop</button> </> ); }
Custom Hook
import { useEffect, useRef, useState } from 'react'; import lottie from 'lottie-web'; function useLottie(options) { const containerRef = useRef(null); const animationRef = useRef(null); const [isLoaded, setIsLoaded] = useState(false); useEffect(() => { if (!containerRef.current) return; animationRef.current = lottie.loadAnimation({ container: containerRef.current, renderer: 'svg', loop: true, autoplay: true, ...options }); animationRef.current.addEventListener('DOMLoaded', () => { setIsLoaded(true); }); return () => { animationRef.current?.destroy(); }; }, [options.path || options.animationData]); return { containerRef, animation: animationRef.current, isLoaded }; } // Usage function MyComponent() { const { containerRef, animation } = useLottie({ path: '/animation.json' }); return <div ref={containerRef} style={{ width: 200, height: 200 }} />; }
Vue Integration
<template> <div ref="container" class="lottie-container"></div> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue'; import lottie from 'lottie-web'; const container = ref(null); let animation = null; onMounted(() => { animation = lottie.loadAnimation({ container: container.value, renderer: 'svg', loop: true, autoplay: true, path: '/animation.json' }); }); onUnmounted(() => { animation?.destroy(); }); </script>
Renderer Comparison
| Renderer | Pros | Cons |
|---|---|---|
| Best quality, DOM access, smaller file | Slower with complex animations |
| Best performance, consistent | No DOM access, larger memory |
| DOM access | Limited feature support |
// SVG (default, recommended) { renderer: 'svg' } // Canvas (performance-critical) { renderer: 'canvas', rendererSettings: { context: canvasContext, // optional: provide 2d context clearCanvas: true } }
dotLottie Format
Smaller file size using
.lottie container format.
npm install @dotlottie/player-component
<script src="https://unpkg.com/@dotlottie/player-component"></script> <dotlottie-player src="/animation.lottie" autoplay loop style="width: 300px; height: 300px" ></dotlottie-player>
Performance Tips
- Use SVG renderer for most cases
- Use canvas for complex animations or many instances
- Reduce frame rate if not needed:
animation.setSubframe(false); // disable subframe rendering - Progressive load for large files:
rendererSettings: { progressiveLoad: true } - Destroy when not visible:
// In viewport observer if (!isVisible) animation.destroy(); - Lazy load animations not immediately visible
Common Patterns
Loading Spinner
function LoadingSpinner({ isLoading }) { if (!isLoading) return null; return ( <Lottie animationData={spinnerAnimation} loop={true} style={{ width: 48, height: 48 }} /> ); }
Interactive Animation
function InteractiveAnimation() { const [isHovered, setIsHovered] = useState(false); const lottieRef = useRef(); useEffect(() => { if (isHovered) { lottieRef.current?.play(); } else { lottieRef.current?.stop(); } }, [isHovered]); return ( <div onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > <Lottie lottieRef={lottieRef} animationData={hoverAnimation} autoplay={false} loop={false} /> </div> ); }
Scroll-Triggered Animation
function ScrollAnimation() { const containerRef = useRef(); const animationRef = useRef(); useEffect(() => { const animation = lottie.loadAnimation({ container: containerRef.current, path: '/scroll-animation.json', autoplay: false }); animationRef.current = animation; const handleScroll = () => { const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight); const frame = scrollPercent * animation.totalFrames; animation.goToAndStop(frame, true); }; window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); animation.destroy(); }; }, []); return <div ref={containerRef} />; }
Finding Animations
- LottieFiles: https://lottiefiles.com - Free and premium animations
- IconScout: https://iconscout.com/lottie-animations
- LordIcon: https://lordicon.com - Animated icons
After Effects Export
Use LottieFiles plugin or Bodymovin to export from After Effects.
Supported Features
- Shapes, masks, trim paths
- Parenting, opacity, transforms
- Text (convert to shapes for best results)
- Image sequences (embedded as base64)
Not Supported
- Video/audio
- 3D layers
- Expressions (limited support)
- Effects like blur, glow
- Very complex masks
Reference Files
- references/react-patterns.md - React integration patterns