Lottie; JSONformatında saklanan vektör tabanlı bir animasyon formatıdır. Airbnb tarafından geliştirilmiştir ve After Effects'te hazırlanan animasyonların web ile mobil uygulamalarda performanslı şekilde oynatılmasını sağlar.
Klasik GIF veya video dosyalarına göre çok daha hafif, vektör olduğu için her ekranda keskin, ve runtime üzerinden değiştirilebilir (renk, hız, durdurma) olduğu için tasarım esnekliği sağlar.
Çok karmaşık 3D efektler veya video içerik için Lottie uygun değildir. Bu tarz durumlarda video veya WebGL daha doğru bir seçimdir.
Hazır animasyon kullanmak için en pratik kaynak lottiefiles.com'dur. Burada binlerce ücretsiz animasyon mevcuttur. Kendi tasarımını yapmak istiyorsan After Effects + Bodymovin eklentisi kullanabilirsin.
lottiefiles.com'a gir, ücretsiz hesap açpublic/lotties/loading.json veya src/assets/lotties/)data.json dosyasını projende kullanNot:Animasyonu indirirken JSON dosyasının boyutuna dikkat et. 200 KB üzeri dosyalar performans sorunu yaratır; mümkünse layer sayısını veya keyframe'leri sadeleştir.
React projelerinde en yaygın kullanılan kütüphane lottie-react'tır. Hafif, modern ve TypeScript desteği vardır.
npm install lottie-reactYarn ile:
yarn add lottie-reactBir component oluştur ve indirdiğin JSON dosyasını import et. Next.js App Router'da bu component "use client" olmak zorundadır çünkü Lottie tarayıcıda çalışan bir kütüphanedir.
"use client";
import Lottie from "lottie-react";
import animationData from "@/assets/lotties/loading.json";
export default function LoadingAnimation() {
return (
<Lottie
animationData={animationData}
loop
autoplay
style={{ width: 200, height: 200 }}
/>
);
}Bu projede de aynı yaklaşım kullanılıyor. CloudAnimation adında ortak bir wrapper var; istediğin JSON dosyasını prop olarak geçirip her yerde tekrar kullanabiliyorsun:
"use client";
import Lottie from "lottie-react";
export default function CloudAnimation({
file,
className,
}: {
file?: object;
className: string;
}) {
return <Lottie animationData={file} loop className={className} />;
}lottie-react; oynatma davranışını kontrol etmek için birçok prop sunar.
autoplay — sayfa açıldığında otomatik başlasın mı? (varsayılan: true)loop — sürekli tekrar etsin mi? (varsayılan: false)<Lottie animationData={data} autoplay={true} loop={false} />Animasyon hızını kontrol etmek için lottieRef'i kullan ve setSpeed metodunu çağır:
"use client";
import Lottie, { LottieRefCurrentProps } from "lottie-react";
import { useRef } from "react";
import data from "@/assets/lotties/wave.json";
export default function FastWave() {
const lottieRef = useRef<LottieRefCurrentProps>(null);
return (
<Lottie
lottieRef={lottieRef}
animationData={data}
onDOMLoaded={() => lottieRef.current?.setSpeed(2)}
loop
/>
);
}<button onClick={() => lottieRef.current?.play()}>Oynat</button>
<button onClick={() => lottieRef.current?.pause()}>Duraklat</button>
<button onClick={() => lottieRef.current?.stop()}>Durdur</button>En etkili lottie kullanım senaryolarından biri, animasyonu kullanıcı etkileşimine bağlamaktır. İki klasik kullanım: hover ile başlatma ve scroll ile oynatma.
"use client";
import Lottie, { LottieRefCurrentProps } from "lottie-react";
import { useRef } from "react";
import data from "@/assets/lotties/heart.json";
export default function HeartButton() {
const lottieRef = useRef<LottieRefCurrentProps>(null);
return (
<div
onMouseEnter={() => lottieRef.current?.play()}
onMouseLeave={() => lottieRef.current?.stop()}
>
<Lottie
lottieRef={lottieRef}
animationData={data}
autoplay={false}
loop={false}
style={{ width: 80, height: 80 }}
/>
</div>
);
}Belirli bir scroll yüzdesinde animasyon karesini değiştirmek için goToAndStop kullanılır:
"use client";
import Lottie, { LottieRefCurrentProps } from "lottie-react";
import { useEffect, useRef } from "react";
import data from "@/assets/lotties/scroll.json";
export default function ScrollAnimation() {
const lottieRef = useRef<LottieRefCurrentProps>(null);
useEffect(() => {
const totalFrames = 60;
const onScroll = () => {
const ratio = window.scrollY / (document.body.scrollHeight - window.innerHeight);
const frame = Math.floor(ratio * totalFrames);
lottieRef.current?.goToAndStop(frame, true);
};
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
return <Lottie lottieRef={lottieRef} animationData={data} autoplay={false} loop={false} />;
}Lottie kütüphanesi tarayıcı API'larıkullanır. Next.js App Router'da SSR ile birlikte kullanmak istersen iki konuya dikkat etmen gerekir: hydration uyumu ve bundle boyutu.
Lottie component'ini sadece client tarafında render etmek için dynamic ile ssr: false kullan:
import dynamic from "next/dynamic";
const HeartButton = dynamic(() => import("./HeartButton"), {
ssr: false,
loading: () => <div style={{ width: 80, height: 80 }} />,
});Sayfanın görünür alanına gelinceye kadar animasyonu yüklememek performansı ciddi şekilde artırır. IntersectionObserver ile yapılabilir:
"use client";
import { useEffect, useRef, useState } from "react";
import Lottie from "lottie-react";
export default function LazyLottie({ data }: { data: object }) {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => entry.isIntersecting && setVisible(true),
{ threshold: 0.2 }
);
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, []);
return (
<div ref={ref} style={{ minHeight: 200 }}>
{visible && <Lottie animationData={data} loop />}
</div>
);
}lottiefiles.com/tools/json-editorile gereksiz layer'ları sildotLottie formatında sıkıştırMobil tarafta lottie-react-native kullanılır. Hem iOS hem Android için doğal performans sunar.
npm install lottie-react-native lottie-ios
# iOS için
cd ios && pod installimport LottieView from "lottie-react-native";
export default function Loading() {
return (
<LottieView
source={require("./assets/loading.json")}
autoPlay
loop
style={{ width: 200, height: 200 }}
/>
);
}import LottieView from "lottie-react-native";
import { useRef } from "react";
import { Pressable } from "react-native";
export default function Heart() {
const lottieRef = useRef<LottieView>(null);
return (
<Pressable onPress={() => lottieRef.current?.play()}>
<LottieView
ref={lottieRef}
source={require("./assets/heart.json")}
autoPlay={false}
loop={false}
style={{ width: 80, height: 80 }}
/>
</Pressable>
);
}Not: Expo kullanıyorsan, expo install lottie-react-native komutu doğru sürümü otomatik yükler ve pod install'a gerek kalmaz.
İndirdiğin animasyonun rengi tasarımına uymuyorsa iki yol var: After Effects'te düzenleyip yeniden export etmek, ya da JSON dosyasını manuel düzenlemek.
Lottie JSON dosyasında renkler 0..1 arası RGBA dizisi olarak tutulur. Örneğin koyu mavi şu şekildedir:
"k": [0.137, 0.412, 0.745, 1]0.137 * 255 ≈ 35, 0.412 * 255 ≈ 105, 0.745 * 255 ≈ 190. Yani rgb(35, 105, 190). Renk değiştirmek için bu değerleri değiştirip kaydetmek yeterlidir.
lottiefiles.com/tools/color-picker aracı, JSON dosyasını yükleyip görsel arayüzden tüm renkleri toplu olarak değiştirmenizi sağlar.
Lottie vektör olduğu için width ve height ile herhangi bir boyutta net görünür. Container'a göre dinamik boyutlanması için CSS yeterlidir:
<Lottie
animationData={data}
loop
className="w-full max-w-md aspect-square"
/>Bazı kullanıcılar (vestibüler hastalıklar, dikkat dağınıklığı) hareket azaltma ayarını açar. Tarayıcı veya işletim sisteminden gelen prefers-reduced-motion medya sorgusunu kontrol ederek animasyonu devre dışı bırakman önemlidir.
"use client";
import Lottie from "lottie-react";
import { useEffect, useState } from "react";
import data from "@/assets/lotties/wave.json";
export default function AccessibleLottie() {
const [reduced, setReduced] = useState(false);
useEffect(() => {
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
setReduced(mq.matches);
const handler = (e: MediaQueryListEvent) => setReduced(e.matches);
mq.addEventListener("change", handler);
return () => mq.removeEventListener("change", handler);
}, []);
if (reduced) return <div aria-hidden="true" />;
return <Lottie animationData={data} loop />;
}Belirti:Konsolda "Hydration failed".
Çözüm: Component'i dynamic ile ssr: false olarak yükle.
Belirti: Sayfada hiçbir şey gözükmüyor.
animationDataprop'una bir nesne mi (object), yoksa URL mu geçiyorsun? URL geçeceksen pathprop'unu kullanÇözüm:
rendererSettings'e preserveAspectRatio: "xMidYMid meet" eklewill-change: transform kullanÇözüm:dotLottie formatına geçiş yap. Aynı animasyon %90'a kadar daha küçük olabilir:
npm install @dotlottie/react-playerimport { DotLottiePlayer } from "@dotlottie/react-player";
<DotLottiePlayer src="/animations/wave.lottie" autoplay loop />Bu kılavuzla artık projende Lottie animasyonlarını kurabilir, kontrol edebilir, performans ve erişilebilirliği gözeterek kullanabilirsin.