[뉴스모아 #1] react-globe.gl 사용하여 메인페이지 지구본 구현

CMK·2024년 1월 13일
0

NewsMoa

목록 보기
1/4

🖐️들어가기에 앞서...

평소에 "세계 뉴스를 한곳에서 보고 싶다" 라는 생각과 "뉴스를 알기 쉽게 요약을 해줫으면 좋겠다" 라는 생각을 하고 있었고 그로인해 "세계 뉴스를 한곳에 모아 번역 및 요약" 이라는 주제로 개인프로젝트 진행을 하게 되었다

세계의 뉴스를 한곳에 모으기 적합한 메인 페이지로 무엇을 할지 고민하였고 그 결과 지구본을 띄우자란 생각하게 되었다 그 후 검색을 통해 간단하게 다양한 기능을 사용할 수 있는 react-globe.gl을 사용하기로 하였다


Next.Js에서의 react-globe의 autoRotate 오류

지구본을 띄우고 지구본에 Hexed Polygons을 그려넣고 나서 문득 생각이 들었다
"어느정도 모양이 나왔으니 한번 지구본을 돌려보자!"
그리고 지구본을 돌리기 위해 globeRef를 만들고 autoRotate를 true를 하는 순간 오류가 발생했다...

Unhandled Runtime Error
TypeError: globeEl.current.controls is not a function

해당 오류는 Next.Js에서 globe.gl을 사용하기 위해 아래와 같이 dynamic import를 사용 하는 점에서 발생하는 것으로 보였다

const Globe = dynamic(() => import("react-globe.gl"), { ssr: false });

https://github.com/vasturiano/react-globe.gl/issues/147

그리고 해당 이슈를 통해 해결을 할 수 있었다

import { useEffect, useRef } from "react";
import Globe, { GlobeMethods } from "react-globe.gl";

export default function GlobeEdit(): JSX.Element {
  const globeRef = useRef<GlobeMethods>();

  useEffect(() => {
    if (!globeRef?.current) return;
    globeRef.current.controls().autoRotate = true;
  }, []);

  return <Globe ref={globeRef} />;
}
import dynamic from "next/dynamic";
import * as S from "./rendingStyles";

const Globe = dynamic(
  () => import("./globe/globeEdit").then((mod) => mod.default),
  {
    ssr: false,
  },
);

export default function Rending(): JSX.Element {
  return (
    <S.Container>
      <Globe />
    </S.Container>
  );
}

아직 정확하게는 왜 해결이 된 건지 잘 모르겠지만
새로운 컴포넌트를 만들어서 react-globe.gl 라이브러리의 내부 모듈을 직접 import 하여 초기화 작업을 수행하고, 그 컴포넌트를 동적으로 import 하여 사용함으로써 이 초기화 작업을 미리 처리하고 나중에 해당 컴포넌트를 렌더링 할 때 사용하였기 때문에 해결이 된 거 같다


globe.gl의 htmlElement의 z-index 문제

autoRotate 문제를 해결 후 마우스 호버시 팝업창이 나오게 만들던중 다른 htmlElement의 z-index의 문제가 발생 하였다
z-index error
위와 같이 팝업창을 다른 htmlElement가 뚫고 나오는 문제다
해당 문제를 해결 하기 위해 팝업창의 z-index를 수정해 보았다

 & .popupContainer {
    position: absolute;
    top: -40px;
    right: -20px;
    display: none;
    pointer-events: auto;
    cursor: pointer;
    z-index: 99999 !important;
    
    &:hover {
      display: block;
    }
  }

하지만 이렇게 z-index를 높여도 거기에 important를 부여해도 결과는 같았다
나의 생각으로는 구체이기 때문에 이러한 문제가 발생 한거 같았다

해당 지구본은 three.js를 이용한 구체이기 때문에 평면이 아닌 입체이다 즉
x, y, z의 입체 공간이 존재한다는 것이고 그로 인해 처음은 한국 이미지가 중국 이미지 보다 카메라에 가깝게 있었고 두 번째는 한국 이미지가 중국 이미지 보다 멀리 있었기 때문에 저렇게 된 것이라 추측했다

그럼 팝업창은 왜 지구본을 뚫고 들어가지 않은가?
그건 HTML 레이어는 항상 다른 WebGL 기반 레이어 위에 위치하는 것이 특징이기 때문이라고
https://github.com/vasturiano/react-globe.gl/issues/122#issuecomment-1498139489
해당 글에서 말해주고 있다

그래서 나는 처음과 계획을 바꾸어서 팝업창은 그대로 htmlElement를 유지하고 각 나라별 마크는 국기 이미지를 넣지 못하지만 WebGL기반을 사용하는 Labels Layer를 사용하기로 하였다

그리고 그 결과 다음과 같이 지구본을 구현하는데 성공하였다

0개의 댓글