3D 포트폴리오
인터페이스
이제 3D 장면이 주로 완성되었으므로 HTML 인터페이스 작업을 시작할 수 있습니다.
Interface.jsx
컴포넌트를 만들고 3D 장면과 동일한 4개의 섹션을 추가합시다:
export const Interface = () => { return ( <div className="interface"> <div className="sections"> {/* HOME */} <section className="section section--bottom">HOME</section> {/* SKILLS */} <section className="section section--right">SKILLS</section> {/* PROJECTS */} <section className="section section--left">PROJECTS</section> {/* CONTACT */} <section className="section section--left">CONTACT</section> </div> </div> ); };
section--bottom
, section--right
, section--left
클래스를 사용하여 섹션 내부의 콘텐츠를 포지셔닝하겠습니다.
현재는 섹션 이름만 추가했으며, 나중에 콘텐츠를 추가할 것입니다.
이제 Interface
컴포넌트를 App
컴포넌트에 추가합시다:
import { Scroll, ScrollControls } from "@react-three/drei"; import { Canvas } from "@react-three/fiber"; import { MotionConfig } from "framer-motion"; import { Experience } from "./components/Experience"; import { config } from "./config"; import { Interface } from "./components/Interface"; function App() { return ( <> <Canvas camera={{ position: [0, 0.5, 5], fov: 42 }}> <color attach="background" args={["#f5f3ee"]} /> <fog attach="fog" args={["#f5f3ee", 10, 50]} /> <ScrollControls pages={config.sections.length} damping={0.1} maxSpeed={0.2} > <group position-y={-1}> <MotionConfig transition={{ duration: 0.6, }} > <Experience /> </MotionConfig> </group> <Scroll html> <Interface /> </Scroll> </ScrollControls> </Canvas> </> ); } export default App;
HTML 인터페이스를 스타일링하기 위해 바닐라 CSS를 사용하여 가능한 한 일반적으로 만들겠습니다. 선호하는 CSS 프레임워크를 사용할 수 있습니다. (저는 대부분의 프로젝트에서 TailwindCSS를 사용했습니다)
index.css
파일에 기본 스타일을 추가합시다:
@import url("https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;700&display=swap"); :root { --primary-color: #4668ee; --text-color: #1a202c; --text-light-color: #555; } #root { width: 100vw; height: 100vh; } body { margin: 0; font-family: "Roboto Slab", serif; } /* ... */ .interface { width: 100vw; display: flex; flex-direction: column; align-items: center; } .sections { max-width: 1200px; width: 100%; } .section { height: 100vh; display: flex; justify-content: center; align-items: center; } .section--top { align-items: flex-start; } .section--bottom { align-items: flex-end; } .section--right { justify-content: flex-end; } .section--left { justify-content: flex-start; }
Google Fonts에서 Roboto Slab 글꼴을 가져와 몇 가지 색상 변수를 정의했습니다.
섹션 컨테이너는 중앙에 위치하며, 큰 화면에서 가독성을 유지하기 위해 max-width
가 1200px
로 설정되었습니다.
섹션은 기본적으로 중심에 위치하며, 100vh
(전체 높이) 의 height
를 가지고 있습니다. section--top
, section--bottom
, section--right
, section--left
클래스를 사용하여 섹션 내부의 콘텐츠를 포지셔닝할 것입니다.
인터페이스가 준비되었습니다. 이제 콘텐츠를 추가합시다!
홈 스크롤 인디케이터
홈 섹션에서 스크롤 인디케이터를 추가하여 사용자가 다른 섹션을 보려면 스크롤해야 한다는 것을 알려줍니다.
먼저, 사용자가 스크롤했는지 여부를 알기 위한 상태를 생성해보겠습니다:
import { useScroll } from "@react-three/drei"; import { useFrame } from "@react-three/fiber"; import { useState } from "react"; export const Interface = () => { const scrollData = useScroll(); const [hasScrolled, setHasScrolled] = useState(false); useFrame(() => { setHasScrolled(scrollData.offset > 0); }); // ... };
그런 다음 홈 섹션에서 variants
객체가 있는 motion.div
를 추가하여 애니메이션 스크롤 인디케이터를 만들 수 있습니다:
// ... import { motion } from "framer-motion"; export const Interface = () => { // ... return ( <div className="interface"> <div className="sections"> {/* HOME */} <section className="section section--bottom"> <motion.div className="scroll-down" initial={{ opacity: 0, }} animate={{ opacity: hasScrolled ? 0 : 1, }} > <motion.div className="scroll-down__wheel" initial={{ translateY: 0, }} animate={{ translateY: 4, }} transition={{ duration: 0.4, repeatDelay: 0.5, repeatType: "reverse", repeat: Infinity, }} ></motion.div> </motion.div> </section> {/* ... */} </div> </div> ); };
우리는 framer motion을 사용하여 불투명도 및 휠 위치를 애니메이션화합니다. 휠이 위아래로 움직이게 하려면 repeat
및 repeatType
속성을 사용합니다.
React Three Fiber: The Ultimate Guide to 3D Web Development
✨ You have reached the end of the preview ✨
Go to the next level with Three.js and React Three Fiber!
Get full access to this lesson and the complete course when you enroll:
- 🔓 Full lesson videos with no limits
- 💻 Access to the final source code
- 🎓 Course progress tracking & completion
- 💬 Invite to our private Discord community
One-time payment. Lifetime updates included.