728x90
안녕하세요 오늘은 React + Three.js 기반의 3D 아바타 컴포넌트 예제를 만들어보겠습니다.
우선 3D 렌더링 라이브러리를 필수로 설치해야합니다
1. 관련 라이브러리 설치
- 이 예제는 TailwindCSS로 스타일링 돼있으니 Tailwind도 같이 세팅해줍니다.
npm install @react-three/fiber @react-three/drei three
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
- react-three-fiber: https://docs.pmnd.rs/react-three-fiber
- @react-three/drei: https://github.com/pmndrs/drei
- Three.js: https://threejs.org/docs/
three.js docs
threejs.org
2. 코드 전체
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
import { OrbitControls, Box, Sphere } from '@react-three/drei'
// 간단한 3D 아바타
function SimpleAvatar() {
const avatarRef = useRef()
const [hovered, setHover] = useState(false)
const [isWaving, setIsWaving] = useState(false)
useFrame((state) => {
if (avatarRef.current) {
// 부드러운 호흡 애니메이션
avatarRef.current.position.y = Math.sin(state.clock.elapsedTime * 2) * 0.1
// 손 흔들기 애니메이션
if (isWaving) {
avatarRef.current.rotation.y = Math.sin(state.clock.elapsedTime * 5) * 0.3
}
}
})
return (
<group
ref={avatarRef}
onClick={() => setIsWaving(!isWaving)}
onPointerOver={() => setHover(true)}
onPointerOut={() => setHover(false)}
scale={hovered ? 1.1 : 1}
>
{/* 머리 */}
<Sphere
args={[0.4, 16, 16]}
position={[0, 1.8, 0]}
>
<meshStandardMaterial color="#ffdbac" />
</Sphere>
{/* 몸통 */}
<Box
args={[0.8, 1.2, 0.4]}
position={[0, 0.6, 0]}
>
<meshStandardMaterial color="#4a90e2" />
</Box>
{/* 왼팔 */}
<Box
args={[0.15, 0.8, 0.15]}
position={[-0.6, 0.8, 0]}
rotation={[0, 0, isWaving ? Math.sin(Date.now() * 0.01) * 0.5 : 0]}
>
<meshStandardMaterial color="#ffdbac" />
</Box>
{/* 오른팔 */}
<Box
args={[0.15, 0.8, 0.15]}
position={[0.6, 0.8, 0]}
>
<meshStandardMaterial color="#ffdbac" />
</Box>
{/* 왼다리 */}
<Box
args={[0.2, 0.8, 0.2]}
position={[-0.2, -0.6, 0]}
>
<meshStandardMaterial color="#2c3e50" />
</Box>
{/* 오른다리 */}
<Box
args={[0.2, 0.8, 0.2]}
position={[0.2, -0.6, 0]}
>
<meshStandardMaterial color="#2c3e50" />
</Box>
{/* 눈 */}
<Sphere
args={[0.05, 8, 8]}
position={[-0.15, 1.9, 0.3]}
>
<meshStandardMaterial color="#000000" />
</Sphere>
<Sphere
args={[0.05, 8, 8]}
position={[0.15, 1.9, 0.3]}
>
<meshStandardMaterial color="#000000" />
</Sphere>
{/* 입 */}
<Box
args={[0.2, 0.05, 0.05]}
position={[0, 1.7, 0.3]}
>
<meshStandardMaterial color="#000000" />
</Box>
</group>
)
}
// 아바타 씬
function AvatarScene() {
return (
<div className="w-full h-96">
<Canvas
camera={{ position: [0, 2, 5], fov: 60 }}
style={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}
>
{/* 조명 */}
<ambientLight intensity={0.6} />
<pointLight position={[10, 10, 10]} intensity={1} />
<pointLight position={[-10, -10, -10]} intensity={0.3} color="#ff6b6b" />
{/* 아바타 */}
<SimpleAvatar />
{/* 컨트롤 */}
<OrbitControls
enablePan={false}
enableZoom={true}
enableRotate={true}
maxDistance={10}
minDistance={3}
/>
</Canvas>
</div>
)
}
// 메인 컴포넌트
function AvatarPortfolio() {
return (
<section className="min-h-screen flex flex-col justify-center items-center bg-gradient-to-br from-blue-900 via-purple-900 to-pink-900 py-20 px-6">
<div className="max-w-4xl mx-auto text-center">
<h2 className="text-5xl font-bold text-white mb-6">
Meet My 3D Avatar
</h2>
<p className="text-xl text-gray-300 mb-12 max-w-2xl mx-auto">
Click on the avatar to make it wave! Drag to rotate, scroll to zoom.
</p>
<div className="bg-black/20 rounded-2xl p-8 backdrop-blur-sm border border-white/10">
<AvatarScene />
</div>
<div className="mt-8 text-gray-300">
<p className="text-lg">
💡 <strong>Interactions:</strong> Click to wave • Hover to scale • Drag to rotate
</p>
</div>
</div>
</section>
)
}
export default AvatarPortfolio
- 먼저 Canvas 로 3D 공간을 생성해줍니다.
- SimpleAvatar 라이브러리의 기본 도형들로 사람 모양을 만들어줍니다
'React' 카테고리의 다른 글
| [React] navigator.share + clipboard로 공유 버튼 간단 구현하기 (0) | 2025.08.25 |
|---|---|
| [React] LottieFiles 애니메이션 적용하기 (0) | 2025.08.21 |
| [React] 웹페이지 메뉴바 드롭다운 만들기 (0) | 2025.08.06 |
| [React] 웹페이지에 간단하게 폭죽 효과 구현하기 (3) | 2025.08.05 |
| [React] GSAP ScrollTrigger 라이브러리 사용해 스크롤에 반응하는 애니메이션 구현하기 (3) | 2025.08.04 |