Lottie.js를 알아보자

Lottie.js를 알아보자

웹 애니메이션을 구현하는 간편하고 효율적인 방법

·

4 min read

디자이너의 스킬업을 위한 lottie.js 완벽 이해하기 강의를 기반으로 작성한 포스팅입니다.


Lottie.js란 무엇인가?

“Lottie는 JSON 기반의 애니메이션 파일이에요. 디자이너는 Lottie를 통해 애니메이션을 이미지만큼 쉽게 옮길 수 있습니다. 용량이 작지만 어떤 기기에서나 작동하고, 크기를 자유롭게 조정해도 해상도가 낮아지지 않아요.”

동일 애니메이션을 gif와 lottie로 만들어보았다. 약 54배의 용량 차이가 나는 것을 확인할 수 있다.

Lottie는 Airbnb에서 만든 애니메이션 라이브러리로, 움직이는 이미지를 GIF나 비디오가 아닌 스크립트로 구현할 수 있다. 벡터 기반의 애니메이션을 JSON 파일로 변환해주기 때문에 GIF 특유의 버벅거림 없이 부드러운 애니메이션을 구현할 수 있다.


Lottie.js 환경설정

Lottie.js는 Web, Android, RN, Ios 모두에 적용이 가능하지만, 환경 별 지원 기능이 다르므로 유의해야 한다. 공식문서 내 supported-features에서 확인 가능하다. https://airbnb.io/lottie/#/supported-features

1) Bodymovin 설치

Lottie를 사용하기 위해서는 After Effects에 Bodymovin이라는 플러그인을 설치해야 한다.

(https://airbnb.io/lottie/#/after-effects 👈 공식문서에 설치과정이 친절하게 설명이 되어있다.)

Bodymovin 설치를 완료했다면, After Effects를 실행하고 상단 메뉴 [window → extensions] 에서 Bodymovin을 확인할 수 있다. (아래 화면과 같이 1→2→3→4 순서로 렌더링 준비를 하면 된다.)

렌더 완~!

Bodymovin 최신버전 오류

현재 공식 문서 내에 안내되어있는 Bodymovin의 버전은 5.12.2이다. 해당 버전을 설치했을 때, 컴포지션이 Bodymovin의 렌더링 대기열에 등록되지 않는 오류를 발견했고, 이전 버전 중 하나인 5.9.0 버전 설치를 통해 해결했다는 을 발견했다. 덕분에 잘 사용하고 있다.

2) JSON 파일 적용

폴더구조 예시

📁 project folder
|
|- 📄 index.html
|- 📄 style.css
|- 📄 animation.js
|- 📜 leaf-data.json

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Lottie Animation</title>
  </head>
  <body>
    <div id="lottie"></div>
    <script src="<https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js>"></script>
    <script src="animation.js"></script>
  </body>
</html>

JavaScript

const params = {
  container: document.getElementById("lottie"),
  renderer: "canvas", // canvas, svg, html 3종류 지원, 주로 svg와 canvas를 사용한다고 함
  loop: true, // false일 경우 한 번만 재생
  autoplay: true, // false일 경우 특정 이벤트를 통한 재생 유도 필수
  path: "leaf-data.json", // Bodymovin을 통해 변환한 JSON 파일 적용
};

const anim = lottie.loadAnimation(params);

Lottie 예제


Lottie.js 사용예제

공식문서의 usage 부분을 참고하면 특정 이벤트에 따라 의도한 대로 애니메이션을 작동할 수 있다. 아래에는 사용한 이벤트와 메소드 몇 가지를 소개해보겠다.

1) 마우스 이벤트 컨트롤

동일한 메서드라도 어떤 이벤트 아래에 위치하고 어떤 순서로 호출되는지에 따라 다양한 애니메이션 스타일을 정의할 수 있다.

  • anim.play() : 애니메이션 재생

  • anim.stop() : 애니메이션 정지

  • anim.pause() : 애니메이션 일시정지

  • anim.setDirection(direction) : 애니메이션 방향 (1은 정방향, -1은 역방향)

  • anim.setSpeed(speed) : 애니메이션 속도 (1은 정상속도)

코드

const loopAni = document.querySelector(".ani-loop");
const hoverAni = document.querySelector(".ani-hover");
const reverseAni = document.querySelector(".ani-reverse");
const clickAni = document.querySelector(".ani-click");
const slowAni = document.querySelector(".ani-slow");

// 기본 loop 애니메이션 재생
const loopAnim = bodymovin.loadAnimation({
  container: loopAni,
  path: `json/${loopAni.dataset.file}.json`,
  renderer: "svg",
  loop: true,
  autoplay: true,
});

// 마우스 오버시 애니메이션 재생
const hoverAnim = bodymovin.loadAnimation({
  container: hoverAni,
  path: `json/${hoverAni.dataset.file}.json`,
  renderer: "svg",
  loop: false,
  autoplay: false,
});
hoverAni.addEventListener("mouseenter", () => {
  hoverAnim.setDirection(1);
  hoverAnim.play();
});
hoverAni.addEventListener("mouseleave", () => {
  hoverAnim.setDirection(-1);
  hoverAnim.play();
});

// 마우스 오버시 애니메이션 반대로 재생
const reverseAnim = bodymovin.loadAnimation({
  container: reverseAni,
  path: `json/${reverseAni.dataset.file}.json`,
  renderer: "svg",
  loop: false,
  autoplay: true,
});
reverseAni.addEventListener("mouseenter", () => {
  reverseAnim.setDirection(-1);
  reverseAnim.play();
});
reverseAni.addEventListener("mouseleave", () => {
  reverseAnim.setDirection(1);
  reverseAnim.play();
});

// 클릭시 애니메이션 재생
const clickAnim = bodymovin.loadAnimation({
  container: clickAni,
  path: `json/${clickAni.dataset.file}.json`,
  renderer: "svg",
  loop: false,
  autoplay: false,
});
clickAni.addEventListener("click", () => {
  clickAnim.play();
});

// 마우스 오버시 애니메이션 느리게 재생
const slowAnim = bodymovin.loadAnimation({
  container: slowAni,
  path: `json/${slowAni.dataset.file}.json`,
  renderer: "svg",
  loop: true,
  autoplay: true,
});
slowAni.addEventListener("mouseenter", () => {
  slowAnim.setSpeed(0.2);
  slowAnim.play();
});
slowAni.addEventListener("mouseleave", () => {
  slowAnim.setSpeed(1);
});

2) 스크롤 애니메이션

스크롤 애니메이션을 구현할 때, 애니메이션 파일의 프레임 수와 스크롤 백분율을 일치시키지 않으면 부자연스럽게 애니메이션이 끊길 수 있으므로, 스크롤 백분율을 적절히 나누고 곱하여 조절해야 한다.

  • progressiveLoad : JSON 애니메이션 파일이 로드될 때 애니메이션 데이터가 점진적으로 로드되는지 여부를 제어하는 옵션

    • true - 애니메이션 데이터가 점진적으로 로드

      • 애니메이션 파일이 크고 로딩 시간이 길어질 수 있는 경우 유용
    • false - 애니메이션 데이터 한 번에 로드

      • 애니메이션 파일이 상대적으로 작고 로딩 시간이 짧은 경우 사용
  • anim.currentRawFrame : 애니메이션의 현재 프레임

  • anim.totalFrames : 애니메이션의 전체 프레임 수

  • anim.goToAndStop(value, isFrame) : 애니메이션을 지정된 프레임으로 이동하고 해당 프레임에서 정지

코드

const elem = document.getElementById("bodymovin");
const animData = {
  container: elem,
  renderer: "svg",
  loop: false,
  autoplay: false,
  rendererSettings: {
    progressiveLoad: false,
  },
  path: "data/illust-about.json",
};
const anim = bodymovin.loadAnimation(animData);

function lottieScroll() {
  let scrollPercent = Math.round(
    (document.documentElement.scrollTop /
      (document.documentElement.scrollHeight - window.innerHeight)) *
      100
  );
  console.log(`스크롤 : ${scrollPercent}%`);
  console.log(`현재 프레임 : ${anim.currentRawFrame}`);
  console.log(`토탈 프레임 : ${anim.totalFrames}`);

  anim.goToAndStop((scrollPercent / 100) * anim.totalFrames, true);
}

window.addEventListener("scroll", lottieScroll);

마무리

문서 내에 gif, video 등의 요소들을 추가할 때 마다 웹사이트가 무거워 지는 것 때문에 고민이 많았는데, Lottie가 해당 문제들을 깔끔하게 해결해 줄 수 있을 것 같아서 앞으로의 작업이 더욱 기대가 된다. Lottie를 자유자재로 활용하기 위해서는 다양한 툴들을 한 번에 다룰 수 있어야 하지만 그만큼 강력한 시너지를 보여주는 것 같다.


참고자료

https://lottiefiles.com/kr/what-is-lottie

https://airbnb.io/lottie/#/after-effects

https://www.udemy.com/course/lottiejs/