Portfolio 3D
Interfaccia
Ora che la nostra scena 3D è principalmente completa, possiamo iniziare a lavorare sull'interfaccia HTML.
Creiamo un componente Interface.jsx
con le stesse 4 sezioni della nostra scena 3D:
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> ); };
Utilizzeremo le classi section--bottom
, section--right
e section--left
per posizionare il contenuto all'interno delle sezioni.
Per il momento abbiamo solo aggiunto i nomi delle sezioni, aggiungeremo il contenuto in seguito.
Aggiungiamo il nostro componente Interface
nel componente 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;
Per stilizzare la nostra interfaccia HTML, useremo vanilla CSS per essere il più generici possibile. Puoi utilizzare il tuo framework CSS preferito se lo desideri. (Ho utilizzato TailwindCSS in molti dei miei progetti)
Aggiungiamo gli stili di default al nostro file 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; }
Abbiamo importato il font Roboto Slab da Google Fonts e definito alcune variabili di colore.
Il contenitore delle sezioni è centrato e ha un max-width
di 1200px
per mantenere una buona leggibilità su schermi grandi.
Le sezioni hanno un height
di 100vh
(altezza completa) e sono centrate di default. Utilizzeremo le classi section--top
, section--bottom
, section--right
e section--left
per posizionare il contenuto all'interno delle sezioni.
La nostra interfaccia è pronta, aggiungiamo il contenuto!
Indicatore di scorrimento nella home
Nella sezione iniziale, aggiungeremo un indicatore di scorrimento per informare l'utente che può scorrere per vedere le altre sezioni.
Per prima cosa, creiamo uno stato per sapere se l'utente ha effettuato uno scroll:
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); }); // ... };
Poi, nella sezione home, possiamo aggiungere un motion.div
con un oggetto variants
per creare un indicatore di scorrimento animato:
// ... 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> ); };
Utilizziamo framer motion per animare l'opacità e la posizione della ruota. Per far muovere la ruota su e giù, usiamo le proprietà repeat
e 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.