lil-gui 코드

공식 사이트는 https://lil-gui.georgealways.com/ 입니다.

패키지 설치는 다음과 같습니다.

npm i lil-gui

필요한 import 문은 다음과 같습니다.

import * as dat from "lil-gui"

사용 코드 예시는 다음과 같습니다.

const gui = new dat.GUI()

const obj = {
  value: 0.5,
  color: "#ff0000"
}

gui.add(obj, "value").min(0).max(1).step(0.01).name("title")
gui.addColor(obj, "color").onChange((v) => { console.log(v, obj.color) })

DNF 오류 발생의 경우 해결 방안

아래의 명령어로 패키지를 설치를 시도함

dnf install epel-release

다음과 같은 에러가 발생

PostgreSQL 10 for RHEL / Rocky 8 - x86_64 61 B/s | 146 B 00:02
Errors during downloading metadata for repository 'pgdg10':
- Status code: 404 for https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-8-x86_64/repodata/repomd.xml (IP: 217.196.149.55)
오류: repo를 위한 메타자료 내려받기에 실패하였습니다 'pgdg10': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried

pgdg10과 관련된 repomd.xml 파일을 다운로드할 수 없다는 에러로 다음 명령을 실행하여 [pgdg10]에서 enabled=1을 enabled=0으로 변경하여 해결함

vi /etc/yum.repos.d/pgdg-redhat-all.repo

Drei 컴포넌트 : Grid

Drei 컴포넌트는 R3F에서 사용할 수 있는 매우 유용한 컴포넌트의 집합입니다. 그 중 Grid 컴포넌트에 대한 사용인데 Grid 이외의 Drei 컴포넌트도 사용되고 있습니다. 예를 들어 StatsGl, Center, Grid, GizmoHelper, GizmoViewcube, GizmoViewport 입니다.

먼저 결과는 다음과 같습니다.

위의 결과에 대한 코드를 하나씩 살펴보면, 먼저 App.jsx 입니다.

import './App.css'
import { Canvas } from '@react-three/fiber'
import MyElement3D from './MyElement3D_Grid'

function App() {
  return (
    <>
      <Canvas shadows camera={{ position: [10, 12, 12], fov: 25 }}>
        <color args={["#303035"]} attach="background" />
        <MyElement3D />
      </Canvas>
    </>
  )
}

export default App

다음은 App 컴포넌트에서 사용하고 있는 MyElement3D_Grid 파일에 대한 코드입니다. 이 파일의 코드를 기능 별로 언급합니다.

먼저 모델 컴포넌트입니다.

import { AccumulativeShadows, Center, Environment, GizmoHelper, GizmoViewcube, GizmoViewport, Grid, OrbitControls, RandomizedLight, Stats, StatsGl, useGLTF } from "@react-three/drei"
import { useControls } from "leva"
import { memo } from "react"

function Robot(props) {
  const { nodes } = useGLTF('./models/model.glb')

  nodes.Scene.traverse(obj => {
    obj.castShadow = true
    obj.receiveShadow = true
  })

  console.log(nodes)
  return (
    <primitive object={nodes.Scene} {...props} />
  )
}

다음은 그림자 컴포넌트입니다. memo 고차 컴포넌트를 사용했는데 그림자일 경우 이렇게 처리하면 장점이 있다고 하네요.

const Shadows = memo(() => (
  <AccumulativeShadows temporal frames={100} color="#000000" colorBlend={0.5} alphaTest={0.9} scale={20}>
    <RandomizedLight amount={8} radius={4} position={[5, 5, -10]} />
  </AccumulativeShadows>
))

이 글의 주인공인 Grid 컴포넌트입니다. 이 컴포넌트의 속성을 UI로 설정하기 위해서 useControls를 사용했습니다.

function MyGrid() {
  const { gridSize, ...gridConfig } = useControls({
    gridSize: [10.5, 10.5],
    cellSize: { value: 0.6, min: 0, max: 10, step: 0.1 },
    cellThickness: { value: 1, min: 0, max: 5, step: 0.1 },
    cellColor: '#6f6f6f',
    sectionSize: { value: 3.3, min: 0, max: 10, step: 0.1 },
    sectionThickness: { value: 1.5, min: 0, max: 5, step: 0.1 },
    sectionColor: '#9d4b4b',
    fadeDistance: { value: 25, min: 0, max: 100, step: 1 },
    fadeStrength: { value: 1, min: 0, max: 1, step: 0.1 },
    followCamera: false,
    infiniteGrid: true
  })

  return (
    <Grid args={gridSize} position={[0, -0.01, 0]} {...gridConfig} />
  )
}

위에서 정의된 컴포넌트들을 사용한 실제 MyElement3D입니다. 리엑트의 좋은 코딩 습관은 말단 컴포넌트는 최대한 JSX 코드만을 반환하는 것으로 작성하는 것입니다. 그러면 코드 가독성이 높아지고 컴포넌트 분리가 효과적으로 됩니다.

function MyElement3D() {
  return (
    <>
      {/* <Stats /> */}
      <StatsGl />

      <OrbitControls makeDefault />
      <Environment preset="city" />
      
      {/* <Center top>
        <Suzi rotation={[-0.63, 0, 0]} scale={2} />
      </Center> */}
      
      <Center>
        <Robot scale={2} />
      </Center>

      <MyGrid />

      <GizmoHelper alignment="bottom-right" margin={[80, 80]}>
        <GizmoViewcube />
        {/* <GizmoViewport axisColors={['#9d4b4b', '#2f7f4f', '#3b5b9d']} labelColor="white" /> */}
      </GizmoHelper>
      
      <Shadows />
    </>
  )
}

export default MyElement3D

이 코드는 추후 제 유튜브 채널을 통해 영상으로 소개될 예정입니다.

지오서비스웹(GEOSERVICE-WEB)으로 만든 통계 지도

지오서비스웹으로 만들 수 있는 통계지도입니다. 입력 데이터는 서울시 행정구역도와 인구 데이터입니다.

먼저 색상 단계 구분도입니다. 서울시 행정구역도에 포함되는 포인트 인구 데이터를 집계해서 얻은 결과입니다.

다음은 핵사곤 영역을 이용한 색상 단계 구분도인데요. 핵사곤 영역은 서울시 행정구역도를 이용해 지오서비스웹의 핵사곤 생성 기능을 이용해 만들었습니다.

다음은 밀도도입니다.

지오서비스웹은 웹에서 누구나 사용할 수 있는 서비스이며 자세한 내용은 아래의 URL을 참조하시기 바랍니다.

지오서비스웹(GEOSERVICE-WEB)