Front-end/web design

Lottie를 이용하여 웹에 애니메이션 주입하기!

kjyook 2023. 5. 30. 01:05
728x90

 웹 페이지를 만들기 위해 작년, 재작년의 페이지들을 보면서 내가 가장 관심이 갔던 부분은 움직이는 그림들이었다. 저런 애니메이션들은 내가 svg, png 파일들을 주입하는 것처럼 그냥 mp4나 gif 파일을 찾아서 주입하면 되는 건가?라는 의문이 들었고 git 주소를 받아서 뜯어본 결과 Lottie를 이용하여 애니메이션을 주입하신 거였다!

 

https://lottiefiles.com/

 

LottieFiles: Download Free lightweight animations for website & apps.

Effortlessly bring the smallest, free, ready-to-use motion graphics for the web, app, social, and designs. Create, edit, test, collaborate, and ship Lottie animations in no time!

lottiefiles.com

이런 기능의 존재를 알게 되고 사용법을 보면서 Lottie를 사용하는 이유를 알 수 있었다.

 

 


Lottie의 장점

  1. Lottie는 동영상 파일들에 비해 압도적으로 낮은 용량을 차지한다. 이는 사용자가 웹을 사용할 때 로딩 속도와 직결되기 때문에 엄청난 장점이라고 생각했다.
  2. Lottie는 해상도에 구애받지 않아 동적으로 크기 조절이 가능하다.
  3. IOS, Andriod, Native, Web 등 다양한 플랫폼에서 사용이 가능하다.
  4. 공식 문서도 존재해서 구현 난이도도 낮다.

 

 


Lottie 사용하는 법

위 사이트에서 나의 마음에 드는 애니메이션을 우선 찾으면 된다! 이 애니메이션을 찾았다고 할 때 이 애니메이션을 주입하는 법은 다음과 같다. 화면을 밑으로 내리면 이런 화면이 나오는데 나의 platform에 맞는 방법을 선택하면 된다.

 

여기서 나의 상황에 맞는걸 골라 사용하면 된다.

<html>을 클릭하면 다음과 같은 화면이 나온다.

위에 옵션들은 내가 필요한 옵션을 클릭하면 되고 밑의 코드를 가져다가 사용하면 되는 것이다.

코드에서 볼 수 있드시 내가 width, height, speed, background를 custom 할 수 있다!

<script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
<lottie-player src="https://assets5.lottiefiles.com/packages/lf20_ZSqxIVbhtx.json"  background="transparent"  speed="1"  style="width: 300px; height: 300px;"  loop controls autoplay></lottie-player>

 

나는 typescript에 이 lottie를 넣는 법을 고민했는데 맨 처음 저 애니메이션을 고르면 나오는 화면에서 Lottie animation URL을 따라가서 다운로드하여 오는 방법을 사용했다.

 

https://sso-feeling.tistory.com/559
위 블로그를 참고하여 작성하였습니다.

이 url을 따라가서 json 파일을 다운받았다.

이 다운받아온 json 파일을 이용해서 나의 웹 페이지에 애니메이션을 넣는 방법은 위 블로그를 보고 따라 한다면 아래와 같이 작성하면 된다.

import React , {useEffect, useRef} from "react";
import styled from "styled-components";
import lottie from "lottie-web";
import Color from "../../shared/Color";
import { style } from "@material-ui/system";

const GetTreasureLottie = ()=>{
     //lottie
  const likecontainer = useRef();
  useEffect(()=>{
    lottie.loadAnimation({
      container: likecontainer.current,
      renderer: 'svg',
      loop: false,
      autoplay:true,
      animationData:require("내가 다운받은 파일의 경로")
     
    })

  },[])
    return(
        <Wrapper>
            <NoMore ref={likecontainer}></NoMore>
          
        </Wrapper>
    )
}

const Wrapper = styled.div`

`;
const NoMore = styled.div`
width: 100%;
height: 100%;
margin: 0 auto;
position: absolute;
margin: 0 auto;
z-index: 1000;
`;


export default GetTreasureLottie;
참고로 나는 next.js를 통해 웹을 만들고 있었는데 public/lottie 폴더에 내가 원하는 파일을 저장했고 경로는 public이 기본으로 지정되어 있어 /lottie/내 파일 이런 식으로 경로를 불러오면 되었다.

그런데 이렇게 작성하니까 드는 생각은 내가 애니메이션을 여러 개 사용하게 된다면 매번 이렇게 코드를 작성하기 너무 번잡하다는 생각이었다. 그래서 Lottie 애니메이션의 경로를 인수로 받고 해당 애니메이션을 띄워주는 컴포넌트를 따로 만들고 싶다는 생각이 들었다.

 


Lottie 컴포넌트의 분리

 

//LottieContainer.tsx
import styled from '@emotion/styled';
import * as S from './LottieContainer.style'
import { useRef, useEffect } from "react";
import Lottie from "lottie-web";

export type LottieContainerProps = {
  path: string;
}

export const LottieContainer = ({ path }: LottieContainerProps) => {
  const lottieContainer = useRef();

    useEffect(() => {
        Lottie.loadAnimation({
        container: lottieContainer.current,
        renderer: "svg",
        loop: true,
        autoplay: true,
        path: path,
        });

        return () => Lottie.destroy();
    }, []);

  return <S.Root ref={lottieContainer} />
}

export default LottieContainer;
//LottieContainer.style.ts
import styled from "@emotion/styled";

export const Root = styled.div`
    width: 100%;
    height: 100%;
`;

path를 props로 받아서 해당 경로에 있는 Lottie를 띄우는 LottieContainer라는 컴포넌트를 작성하였다. 위와 같이 작성하면 재활용이 용이했다!

 

<LottieContainer path={"/lottie/purple_computer.json"} />

단 한줄로 활용이 가능했다!

가독성도 좋아지고 재활용도 쉬워져서 굉장히 만족스럽다

 

 


Typescript에서 발생하는 build error 수정

내가 보고 공부한 방식이 js방식이라 그런지 분명 npm run dev를 했을 때는 실행도 잘되고 화면에 잘 나왔는데 build를 하니까 빨간 줄이던 게 error가 발생하였다. 당연히 type error였다. Lottie.loadAnimation 함수 안의 container의 type error였다. 따라서 아래와 같이 수정을 해줬다.

 

import styled from '@emotion/styled';
import * as S from './LottieContainer.style'
import { useRef, useEffect } from "react";
import Lottie from "lottie-web";

export type LottieContainerProps = {
  path: string;
}

export const LottieContainer = ({ path }: LottieContainerProps) => {
  const lottieContainer = useRef<HTMLDivElement>(null);

    useEffect(() => {
        Lottie.loadAnimation({
        container: lottieContainer.current as HTMLDivElement,
        renderer: "svg",
        loop: true,
        autoplay: true,
        path: path,
        });

        return () => Lottie.destroy();
    }, []);

  return(
    <>
      <S.Root ref={lottieContainer} />
    </>
  )
}

export default LottieContainer;

 

 

728x90