الحافظة ثلاثية الأبعاد
الواجهة
الآن بعد أن أنجزنا مشهدنا ثلاثي الأبعاد بشكل رئيسي، يمكننا البدء في العمل على واجهة HTML.
دعونا ننشئ مكون Interface.jsx
مع نفس الأقسام الأربعة كمشهد ثلاثي الأبعاد لدينا:
export const Interface = () => { return ( <div className="interface"> <div className="sections"> {/* الصفحة الرئيسية */} <section className="section section--bottom">HOME</section> {/* المهارات */} <section className="section section--right">SKILLS</section> {/* المشاريع */} <section className="section section--left">PROJECTS</section> {/* الاتصال */} <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 الخاصة بنا، سنستخدم vanilla 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; }
لقد قمنا باستيراد خط Roboto Slab من Google Fonts وقمنا بتعريف بعض متغيرات الألوان.
يتم توسيط حاوية الأقسام وتحتوي على max-width
بـ 1200px
للحفاظ على قراءة جيدة على الشاشات الكبيرة.
الأقسام لها height
بـ 100vh
(ارتفاع كامل) ويتم توسيطها افتراضياً. سنستخدم الفئات 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); }); // ... };
ثم في قسم الصفحة الرئيسية، يمكننا إضافة motion.div
مع كائن variants
لإنشاء مؤشر تمرير متحرك:
// ... import { motion } from "framer-motion"; export const Interface = () => { // ... return ( <div className="interface"> <div className="sections"> {/* الصفحة الرئيسية */} <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.