Lottie — biblioteka z otwartym kodem źródłowym od Airbnb, która odtwarza animacje wektorowe wyeksportowane z Adobe After Effects do formatu JSON przez wtyczkę Bodymovin. Animacje są renderowane programowo, bez utraty jakości na każdej rozdzielczości ekranu. Według danych GitHub (2026), Lottie jest używane w ponad 50 000 projektów na iOS, Android i Web. Więcej o innych rodzajach animacji przeczytasz w ogólnym przewodniku po animacji.
Najważniejsze
Lottie — wieloplatformowa biblioteka do odtwarzania animacji wektorowych, opracowana w Airbnb w 2015 roku. Rozwiązuje problem ciężkich plików wideo i rastrowych arkuszy sprite'ów: projektant tworzy animację w After Effects, eksportuje przez Bodymovin do JSON, a programista osadza ten plik w aplikacji mobilnej. Lottie renderuje animację programowo przez Canvas, Core Animation lub Skia, w zależności od platformy.
Główną zaletą Lottie jest skalowalność animacji wektorowej bez utraty jakości na każdym ekranie: od zegarków Apple Watch po telewizory 4K. Rozmiar pliku JSON animacji wynosi zwykle 5–50 KB, co jest kilkadziesiąt razy mniejsze niż równoważny plik wideo. Według Airbnb Engineering (2025), Lottie obsługuje ponad 80% możliwości Adobe After Effects, w tym maski, efekty, krzywe i wyrażenia.
Bodymovin — to wtyczka do After Effects (darmowa, GitHub), która serializuje kompozycję do formatu JSON zrozumiałego dla środowiska uruchomieniowego Lottie. Obsługiwane są wersje After Effects CC 2018 i nowsze. W przypadku złożonych animacji z dużą liczbą klatek kluczowych zaleca się używanie dotLottie — formatu opartego na Lottie JSON, ale skompresowanego i spakowanego w jeden plik.
Lottie wykorzystuje warstwową architekturę renderowania, która dostosowuje się do możliwości platformy. Na Androidzie animacja rysowana jest przez Canvas API — własny renderer Lottie (LottieDrawable), który nie używa systemowych animacji. Na iOS Lottie opiera się na Core Animation Layers, co zapewnia wysoką wydajność i 60 FPS. We Flutter Lottie używa Skia Canvas przez CustomPainter.
Renderowanie przebiega w trzech etapach: parsowanie JSON — analiza animacji w LottieComposition (wszystkie warstwy, kształty, klatki kluczowe); interpolacja — obliczanie wartości pośrednich między klatkami kluczowymi z uwzględnieniem krzywych easing; rysowanie — renderowanie bieżącej klatki na Canvas lub przez Core Animation. Lottie obsługuje akcelerację sprzętową: na Androidzie — przyspieszenie przez Canvas z Hardware Accelerator, na iOS — CALayer z wbudowanym przyspieszeniem GPU Core Animation.
| Platforma | Renderer | Akceleracja sprzętowa | Biblioteka |
|---|---|---|---|
| Android | Canvas (LottieDrawable) | Hardware Accelerator (API 14+) | com.airbnb.lottie |
| iOS | Core Animation (CALayer) | GPU (Metal, OpenGL) | Lottie-iOS |
| Flutter | Skia Canvas (CustomPainter) | Impeller (Flutter 3.16+) | lottie_flutter |
| React Native | Native bridge | Zależy od platformy | lottie-react-native |
Na Androidzie LottieAnimationView rozszerza AppCompatImageView i przejmuje cały cykl ładowania i renderowania. Plik JSON umieszczany jest w folderze res/raw lub assets. LottieAnimationView obsługuje zarządzanie odtwarzaniem — play, pause, resume, setFrame, setProgress, repeat, speed — oraz nasłuchiwanie przez AnimatorUpdateListener i AnimatorListener.
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:lottie_rawRes="@raw/loading_animation"
app:lottie_autoPlay="true"
app:lottie_loop="true" />
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieListener
// Programowa konfiguracja LottieAnimationView
val lottieView = LottieAnimationView(context).apply {
setAnimation(R.raw.celebrate_animation)
repeatCount = ValueAnimator.INFINITE
speed = 1.5f
addAnimatorUpdateListener { animator ->
val progress = animator.animatedValue as Float
progressBar.progress = (progress * 100).toInt()
}
playAnimation()
}
// Ładowanie z assets i buforowanie
lottieView.setAnimation("animations/confetti.json")
lottieView.setCacheStrategy(LottieAnimationView.CacheStrategy.Strong)
// LottieDrawable — niestandardowe renderowanie bez View
val drawable = LottieDrawable().apply {
setComposition(
LottieCompositionFactory.fromRawRes(context, R.raw.star)
.addListener { composition -> composition?.let { setComposition(it); play() } }
)
}
Najlepsze praktyki Android: używaj setCacheStrategy(CacheStrategy.Strong) dla często powtarzanych animacji — kompozycja jest buforowana w pamięci, a każda nowa instancja nie parsuje JSON od nowa. Dla list (RecyclerView) używaj LottieAnimationView z enableMergePathsForKitKatAndAbove(true) i disableExtraScaleModeForOlderWorkarounds() w celu optymalizacji renderowania. Dla animacji z przezroczystym tłem ustaw android:layerType="hardware" dla akceleracji GPU.
Na iOS AnimationView — główna klasa Lottie dla UIKit i SwiftUI. Jest podłączana przez Swift Package Manager lub CocoaPods. Pliki JSON dodawane są do bundle projektu. AnimationView automatycznie określa scale (logiczną gęstość ekranu) i używa Core Animation do renderowania warstw z 60 FPS.
import Lottie
// UIKit: AnimationView z ręcznym sterowaniem
let animationView = AnimationView(name: "confetti")
animationView.frame = view.bounds
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
animationView.animationSpeed = 1.5
animationView.play(fromProgress: 0, toProgress: 0.5) { finished in
print("Segment animacji zakończony: \(finished)")
}
view.addSubview(animationView)
// UIKit: animacja z postępem (do powiązania ze zdarzeniem)
animationView.play(fromFrame: AnimationFrameTime(30),
toFrame: AnimationFrameTime(90))
// SwiftUI: LottieView jako UIViewRepresentable
import Lottie
import SwiftUI
struct LottieView: UIViewRepresentable {
let name: String
var loopMode: LottieLoopMode = .loop
@Binding var progress: CGFloat
func makeUIView(context: Context) -> AnimationView {
let view = AnimationView(name: name)
view.contentMode = .scaleAspectFit
view.loopMode = loopMode
return view
}
func updateUIView(_ uiView: AnimationView, context: Context) {
uiView.currentProgress = progress
}
}
// Użycie w SwiftUI
LottieView(name: "loading", progress: $animationProgress)
.frame(width: 100, height: 100)
Najlepsze praktyki iOS: dla animacji uruchamianych zaraz po załadowaniu używaj animationView.play(fromProgress: 0, toProgress: 1) z loopMode = .playOnce dla jednorazowych efektów akcentujących. Dla Lottie w UITableView/UICollectionView używaj AnimationView z buforowanym plikiem animacji przez LottieAnimation.cached. Renderowanie dużej liczby warstw (50+) może powodować spadek FPS — w takich przypadkach włączaj renderingEngine = .mainThread (domyślnie) lub .coreAnimation dla macOS.
Lottie zasadniczo różni się od plików wideo: nie przechowuje pikseli, ale opisuje kształty wektorowe, ich transformacje i krzywe zmian w czasie. Wideo (MP4, WebM) — to sekwencja rastrowych klatek o stałej rozdzielczości. Różnica przejawia się w rozmiarze pliku, jakości skalowania, interaktywności i wydajności.
| Parametr | Lottie (JSON) | Wideo (MP4) | GIF |
|---|---|---|---|
| Rozmiar pliku | 5–50 KB | 200–2000 KB | 500–5000 KB |
| Jakość skalowania | Wektorowa (nieskończona) | Stała (pikselowa) | Stała |
| Interaktywność | Postęp, prędkość, pauza, zmiana koloru | Nie | Nie |
| Kanał alfa (przezroczystość) | Natywny | Wymaga kodeka | Obsługiwany |
| Wydajność (CPU) | Niskie obciążenie | Średnie (dekodowanie) | Wysokie (dekodowanie rastrowe) |
Kiedy wybrać Lottie: ikony ładowania, polubienia/animacje reakcji, ekran onboard, akcentujące mikroanimacje przycisków. Dla złożonych scen z efektami 3D, realistycznym oświetleniem lub fotorealistycznymi postaciami wideo pozostaje bardziej praktycznym wyborem. Lottie nie jest przeznaczony do odtwarzania długich scen (ponad 10 sekund) — optymalny czas trwania jednej animacji to 2–5 sekund.
Wydajność Lottie zależy od liczby warstw, złożoności masek i efektów oraz od renderera. Aby utrzymać 60 FPS na urządzeniach średniej klasy, postępuj zgodnie z zaleceniami: ogranicz liczbę warstw do 30–40 na scenę, unikaj nakładających się zagnieżdżonych pre-compositions, używaj dotLottie dla złożonych animacji.
// Optymalizacja Lottie dla RecyclerView
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.airbnb.lottie.LottieCompositionFactory
// Buforowanie kompozycji w pamięci
private val cache = LottieCompositionFactory.setCacheStrategy(CacheStrategy.Strong)
// Pula LottieAnimationView do ponownego użycia
class LottiePool {
private val pool = LinkedList<LottieAnimationView>()
fun acquire(context: Context): LottieAnimationView {
return pool.poll() ?: LottieAnimationView(context)
}
fun release(view: LottieAnimationView) {
view.pauseAnimation()
view.cancelAnimation()
pool.add(view)
}
}
// Wyłączanie niepotrzebnych funkcji
lottieView.enableMergePathsForKitKatAndAbove(true)
lottieView.setHardwareAcceleration(true)
lottieView.setMaxFrame(60) // Ograniczenie liczby klatek
Dodatkowe optymalizacje: włączaj enableMergePathsForKitKatAndAbove(true) dla urządzeń z Android 4.4+ — scala to nakładające się kontury w jedną ścieżkę, zmniejszając liczbę draw calls. Używaj dotLottie zamiast JSON — format binarny kompresuje animację o 50–80% dzięki serializacji protobuf, co skraca czas parsowania. Dla animacji w RecyclerView ustawiaj repeatCount = 0 (jednokrotne odtworzenie) i zatrzymuj animację podczas przewijania przez recyclerView.addOnScrollListener. Według Airbnb Engineering Blog (2025), te środki zmniejszają obciążenie CPU nawet o 40%.
Często zadawane pytania
Używaj dotLottie — formatu binarnego opartego na protobuf, który kompresuje JSON o 50–80%. W After Effects eksportuj przez Bodymovin z ustawieniem «Glyphs» = None (jeśli tekst nie jest potrzebny), wyłącz zbędne prowadnice i warstwy prowadzące. Usuń niewidoczne warstwy i warstwy z 0% opacity przed eksportem.
Sprawdź minimalną wersję SDK: Lottie dla Androida obsługuje API 14+, ale niektóre efekty (Path Morphing, Gradient) działają tylko z API 21+. Na iOS Lottie wymaga iOS 11+. Dla starych urządzeń użyj fallback — statycznej klatki PNG z animacji. Ładuj animacje asynchronicznie przez LottieCompositionFactory z obsługą błędów przez LottieListener.onFailure.
Tak, przez LottieDynamicProperties lub KeyPath. Ustaw Layer Name w After Effects (np. «icon-fill»), następnie w kodzie: lottieView.addValueCallback(KeyPath(«icon-fill»), LottieProperty.COLOR) { Color.GREEN }. Pozwala to dostosować animację do motywu aplikacji bez tworzenia duplikatów plików. Dla iOS używaj AnimationView.setValueProvider(ColorValueProvider).
Lottie — format do odtwarzania wcześniej stworzonej animacji z After Effects. Rive — interaktywna animacja z State Machine, trigerami i wejściami. Lottie nadaje się do pasywnych animacji (ładowanie, polubienia, ekrany powitalne). Rive — do gier, interaktywnych elementów UI, animacji z informacją zwrotną na działania użytkownika. Rive wymaga własnego edytora, Lottie działa przez znany After Effects.
Na Androidzie: lottieView.addAnimatorListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { ... } }). Na iOS: animationView.play { finished in }. W SwiftUI: używaj Binding dla currentProgress z onChange. Dla Kotlin Multiplatform używaj LottieAnimatable z biblioteki lottie-compose.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również