Portofolio 3D
Antarmuka
Sekarang setelah kita menyelesaikan sebagian besar adegan 3D kita, kita bisa mulai mengerjakan antarmuka HTML.
Mari kita buat komponen Interface.jsx
dengan 4 bagian yang sama seperti adegan 3D kita:
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> ); };
Kita akan menggunakan kelas section--bottom
, section--right
, dan section--left
untuk memposisikan konten di dalam bagian-bagian tersebut.
Untuk saat ini kita hanya menambahkan nama bagian-bagiannya, kita akan menambahkan konten nanti.
Mari tambahkan komponen Interface
kita ke dalam komponen 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;
Untuk menata antarmuka HTML kita, kita akan menggunakan vanilla CSS agar lebih umum. Anda dapat menggunakan framework CSS favorit Anda jika Anda mau. (Saya menggunakan TailwindCSS pada sebagian besar proyek saya)
Mari tambahkan gaya default ke file index.css
kita:
@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; }
Kami mengimpor font Roboto Slab dari Google Fonts dan mendefinisikan beberapa variabel warna.
Kontainer bagian-bagian berada di tengah dan memiliki max-width
sebesar 1200px
untuk menjaga keterbacaan yang baik pada layar besar.
Bagian-bagian memiliki height
sebesar 100vh
(tinggi penuh) dan berada di tengah secara default. Kita akan menggunakan kelas section--top
, section--bottom
, section--right
, dan section--left
untuk memposisikan konten di dalam bagian-bagian tersebut.
Antarmuka kita sudah siap, mari tambahkan kontennya!
Indikator Gulir Home
Pada bagian home, kita akan menambahkan indikator gulir untuk memberitahu pengguna bahwa mereka dapat menggulir untuk melihat bagian lainnya.
Pertama, mari kita buat state untuk mengetahui apakah pengguna sudah menggulir:
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); }); // ... };
Kemudian di bagian home, kita dapat menambahkan motion.div
dengan objek variants
untuk membuat indikator gulir yang animatif:
// ... 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> ); };
Kami menggunakan framer motion untuk menganimasikan opasitas dan posisi roda. Untuk membuat roda bergerak ke atas dan ke bawah, kami menggunakan properti repeat
dan 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.