[React-Native] svg를 이용한 애니메이션 효과 구현

하태현·2021년 4월 8일
0

구현할 애니메이션 예제 코드

CSS에서는 위의 svg 파일을 이용해 애니메이션을 적용하면 간단하게 걸어가는 강아지 애니메이션과 움직이는 배경을 쉽게 구현 할 수 있었다.

나에게 주어진 과제는 react-native-game-engine 라이브러리를 이용해서 해당 기능을 똑같이 구현 해보는 것 이었다.

우선 게임엔진 라이브러리는 1render/16m(60fps) 의 스펙을 가지고 있다.
🔵 60FPS(60render/1s)

render() {
    const {step, bgStep} = this.state;

    return (
      <SvgCssUri
          width={width2 * 1.6}
          height={height2 * 1.6}
          viewBox={[vWidth2 * bgStep, 0, vWidth2, vHeight2].join(' ')}
          uri={
            'https://s3-us-west-2.amazonaws.com/s.cdpn.io/57786/background.svg'
          }
          style={{position: 'absolute', top: 50}}
        />

      <GameLoop style={styles.container} onUpdate={this.updateHandler}>
        <SvgCssUri
          width={width * 0.4}
          height={height * 0.4}
          viewBox={[0, vHeight * step, vWidth, vHeight + 10].join(' ')}
          uri={
            'https://s3-us-west-2.amazonaws.com/s.cdpn.io/57786/dog-walk.svg'
          }
          style={{position: 'absolute', top: 100}}
        />
      </GameLoop>
    );
  }

onUpdate 함수는 렌더 될 때마다 실행되는 함수.
<GameLoop></GameLoop> 내부의 로직이 반복 되는 것이다.

내가 구현한 방법은 강아지 그림이 총 9개 인데 이미지 전체 높이를 9등분 해서 vHeight 로 지정해주고 onUpdate 안에서 step을 변경(증가 or 감소)시켜 주어 걸어가는 모션을 구현했다.

한마디로 설명하면 전체 이미지 중에서 렌더 될 때마다 보여지는 부분을 이동 시키는 개념이다.

강아지의 경우엔 y축으로 이동해야해서 height를 변경하고, 배경은 x축으로 이동해야 하니 width를 변경했다.

그냥 이렇게만 했을 경우엔 16ms마다 배경도 지정한 만큼 움직이고, 강아지도 엄청 빠르게 걷는다.

그래서 속도제어가 관건인데 onUpdate 를 이용해 제어가 가능했다.

updateHandler = ({touches, screen, time}: GameLoopUpdateEventOptionType) => {
    const result = {...this.state};
    const FPS = Math.floor((1 / (Date.now() - this.elapse_time)) * 1000);

    this.elapse_time = Date.now(); // 현재 시간으로 초기화
    this.num += 1;
    result.fps = FPS;

    if (this.state.step > 7) result.step = 0;
    if (this.state.bgStep > 1) result.bgStep = 0;
    if (this.num % 10 === 0) result.step += 1;
    result.bgStep += 0.001;

    this.setState(result);
  };

우선 result.bgStep += 0.001; 배경은 정말 조금씩 이동하면 된다. bgStep 라는 상태를 업데이트 시켜준다.
실제 이미지에서 연속된 부분을 계속 보여줘야 하므로 이 방법을 선택했다.

강아지는 이동 해야할 height가 정해져 있기 때문에 속도 제어하기가 힘들었다. 16ms마다 정해진 높이(ex: 200px)를 이동하면 너무 빠르게 걷는다. 이를 해결할 방법으로 16ms마다 num이란 변수를 1씩 증가 시킨다.
if (this.num % 10 === 0) result.step += 1;
이렇게 하면 160ms마다 강아지가 움직일 것이다.

전체 코드- github

profile
왜?를 생각하며 개발하기, 다양한 프로젝트를 경험하는 것 또한 중요하지만 내가 사용하는 기술이 어떤 배경과 이유에서 만들어진 건지, 코드를 작성할 때에도 이게 최선의 방법인지를 끊임없이 질문하고 고민하자. 이 과정은 앞으로 개발자로 커리어를 쌓아 나갈 때 중요한 발판이 될 것이다.

2개의 댓글

comment-user-thumbnail
2022년 3월 31일

태현님 안녕하세요, react native game engine을 통해 앱 내에 포함시킬 미니게임을 개발해야 하는 상황인데, 국내 레퍼런스가 너무 부족해서 힘들어하고 있습니다ㅠㅠ...
혹시 제가 연락을 드릴 수 있는 루트가 있을까요? (크게는 프리랜서 구인의 생각도 있으나, 시도해본 사람 자체가 너무나도 소수인 부분입니다.)

1개의 답글