Transizioni con shader
In questa lezione impareremo a creare transizioni utilizzando shader.
Il primo effetto che creeremo è un effetto di transizione dello schermo:
Abbiamo il controllo totale sull'effetto di transizione, possiamo cambiare la durata, la funzione di easing e lo shader stesso.
Il secondo effetto che creeremo è un effetto di transizione del modello:
Quando il modello svanisce viene dissolto e i colori si lavano nel bianco, accade il contrario quando riappare.
Pacchetto iniziale
Ecco tutti i modelli 3D che useremo in questa lezione creati da Ergoni e concessi in licenza sotto Creative Commons Attribution:
Il pacchetto iniziale utilizza i seguenti pacchetti:
- Tailwind CSS per il design
- Framer Motion per le animazioni
- Jotai library per gestire lo stato condiviso tra i componenti
I due font utilizzati sono Kanit e Rubik Doodle Shadow, entrambi da Google Fonts.
Sentiti libero di modificare qualsiasi componente secondo le tue preferenze.
Puoi regolare i colori giocando con i controlli di Leva nell'angolo in alto a destra. Una volta trovati i colori che ti piacciono, aggiungi la proprietà hidden al componente Leva in App.jsx:
// ... function App() { // ... return ( <> <Leva hidden /> {/* ... */} </> ); } // ...
Transizione dello schermo
Iniziamo creando il nostro effetto di transizione dello schermo. Creeremo un componente chiamato ScreenTransition che gestirà l'effetto di transizione.
Creiamo un nuovo file chiamato ScreenTransition.jsx nella cartella components:
export const ScreenTransition = ({ transition, color }) => { return ( <mesh> <planeGeometry args={[2, 2]} /> <meshBasicMaterial color={color} /> </mesh> ); };
In questo componente, stiamo creando un piano colorato che coprirà l'intero schermo. Utilizzeremo questo piano per effettuare la transizione tra gli schermi.
Il nostro componente accetta due proprietà:
- transition: un booleano per sapere se il componente dovrebbe mostrare l'effetto di transizione
- color: il colore principale dell'effetto di transizione
Aggiungiamo il componente ScreenTransition a App.jsx:
// ... import { ScreenTransition } from "./components/ScreenTransition"; function App() { // ... return ( <> {/* ... */} <Canvas camera={{ position: [0, 1.8, 5], fov: 42 }}> <color attach="background" args={[backgroundColor]} /> <fog attach="fog" args={[backgroundColor, 5, 12]} /> <ScreenTransition transition color="#a5b4fc" /> <Suspense> <Experience /> </Suspense> </Canvas> </> ); } export default App;
Per ora forziamo la visualizzazione dell'effetto di transizione passando true alla prop transition. Aggiungeremo in seguito la logica per controllare l'effetto di transizione.
Regola il colore a tuo piacimento. Se lo cambi, assicurati di aggiornare il colore nel file index.css per evitare un flash di colore quando il sito web viene caricato:
// ... html { background-color: #a5b4fc; }
Il piano è al centro della scena.
Piano a schermo intero
Vogliamo che il nostro piano copra l'intero schermo. Potremmo utilizzare le dimensioni del viewport e farlo fronteggiare la telecamera, ma vogliamo anche che sia sopra a tutto il resto.
Per raggiungere questo scopo, Drei fornisce un componente Hud che renderà i suoi figli sopra a tutto il resto. Possiamo aggiungere una telecamera fissa al componente Hud per assicurarci che sia perfettamente allineata con il nostro piano:
import { Hud, OrthographicCamera } from "@react-three/drei"; export const ScreenTransition = ({ transition, color }) => { return ( <Hud> <OrthographicCamera makeDefault top={1} right={1} bottom={-1} left={-1} near={0} far={1} /> <mesh> <planeGeometry args={[2, 2]} /> <meshBasicMaterial color={color} /> </mesh> </Hud> ); };
Utilizziamo una OrthographicCamera per coprire facilmente l'intero schermo qualunque sia la distanza tra la telecamera e il piano.
Il piano ora copre l'intero schermo.
Logica di transizione
Un'ultima cosa prima di creare il nostro shader personalizzato, definiamo uno stato di transizione in UI.jsx
:
// ... import { atom } from "jotai"; export const transitionAtom = atom(true); // ...
Impostiamo il valore iniziale su true per iniziare con un effetto di dissolvenza dopo il caricamento del sito web.
Useremo questo stato per controllare l'effetto di transizione.
Sempre in UI.jsx
, definiamo due costanti per controllare la durata e il ritardo dell'effetto di transizione:
// ... export const TRANSITION_DELAY = 0.8; export const TRANSITION_DURATION = 3.2; // ...
Ora sostituiamo la chiamata alla funzione setScreen
con una nuova che gestirà l'effetto di transizione:
// ... import { useAtom } from "jotai"; import { useRef } from "react"; // ... export const UI = () => { // ... const [transition, setTransition] = useAtom(transitionAtom); const timeout = useRef(); // ... const transitionToScreen = (newScreen) => { setTransition(true); clearTimeout(timeout.current); timeout.current = setTimeout(() => { setScreen(newScreen); setTransition(false); }, TRANSITION_DURATION * 1000 + TRANSITION_DELAY * 1000); }; // ... };
Invece di impostare direttamente il nuovo schermo, impostiamo lo stato della transizione su true e usiamo un setTimeout per impostare il nuovo schermo dopo che l'effetto di transizione è concluso (la durata dell'effetto di transizione più il ritardo).
Ora la nostra funzione è pronta, cerca le chiamate a setScreen
nel componente UI
e sostituiscile con transitionToScreen
.
Da home a menu:
<motion.button onClick={() => transitionToScreen("menu")} // ... >
E da menu a home:
<motion.button onClick={() => transitionToScreen("home")} // ... >
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.