Wawa Sensei logo

3D पोर्टफोलियो

Starter pack

इंटरफेस

अब जब कि हमने अपने 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 इंटरफेस को स्टाइल करने के लिए, हम 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;
}

हमने Google Fonts से Roboto Slab फॉन्ट को इम्पोर्ट किया है और कुछ कलर वैरिएबल्स को परिभाषित किया है।

सेक्शन कंटेनर को सेंटर में स्थित किया गया है और इसका max-width 1200px है ताकि बड़े स्क्रीन पर अच्छी पठनीयता बनी रहे।

सेक्शन की height 100vh (पूरी ऊंचाई) होती है और डिफॉल्ट रूप से सेंटर में होते हैं। हम section--top, section--bottom, section--right और section--left क्लासेस का उपयोग करके सेक्शन की सामग्री को स्थिति देंगे।

हमारा इंटरफेस तैयार है, अब सामग्री जोड़ते हैं!

होम स्क्रोल इंडिकेटर

होम सेक्शन पर, हम एक स्क्रोल इंडिकेटर जोड़ेंगे जो यूज़र को बताएगा कि वह अन्य सेक्शन देखने के लिए स्क्रोल कर सकता है।

पहले, आइए एक state बनाते हैं यह जानने के लिए कि यूज़र ने स्क्रोल किया है या नहीं:

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 object के साथ जोड़ सकते हैं ताकि एक animated स्क्रोल इंडिकेटर बनाया जा सके:

// ...
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 का उपयोग कर रहे हैं ताकि opacity और व्हील पोजीशन को animate कर सकें। व्हील को ऊपर और नीचे ले जाने के लिए, हम repeat और repeatType properties का उपयोग करते हैं।

End of lesson preview

To get access to the entire lesson, you need to purchase the course.