ट्रेल्स

Starter pack

आइए ट्रेल्स की दुनिया में गोता लगाएँ! ट्रेल्स आपके सीन में गति का एहसास जोड़ने का एक शानदार तरीका हैं। इन्हें विभिन्न प्रभावों, जैसे कि लाइट ट्रेल्स, धुएं के ट्रेल्स, या किसी गतिशील वस्तु के ट्रेल के रूप में बनाया जा सकता है।

यहाँ वह अंतिम प्रोजेक्ट है जिसे हम साथ में बनाएंगे:

हम एक कस्टम ट्रेल कर्सर का उपयोग करके एक सरल ट्रेल प्रभाव बनाना शुरू करेंगे। फिर हम drei के Trail component की जांच करेंगे ताकि आप जो प्रीव्यू में कॉमेट्स देखें उन्हें बना सकें।

स्टार्टर प्रोजेक्ट

स्टार्टर प्रोजेक्ट में कई चीजें शामिल हैं जिन्हें हमने पिछले पाठों में पहले ही कवर किया है:

  • स्क्रॉल और सहायक कैमरा मूवमेंट और एनीमेशन को संभालने के लिए ScrollControls component। यदि आपको एक रिफ्रेशर की आवश्यकता है, तो आप समर्पित स्क्रॉल पाठ देख सकते हैं।
  • Bloom और Vignette जैसे पोस्टप्रोसेसिंग प्रभाव, जिसमें एक प्यारा सा GodRays प्रभाव जोड़ा गया है। यदि आपको एक रिफ्रेशर की आवश्यकता है, तो पोस्ट प्रोसेसिंग पाठ अवश्य देखें।
  • जिसे हमने Particles पाठ में बनाया था, समायोजित मापदंडों के साथ।

इसके अलावा, मैंने जल्दी से UI डिज़ाइन करने के लिए Tailwind CSS का उपयोग किया। यदि आप Tailwind CSS से परिचित नहीं हैं, तो आप UI भाग छोड़ सकते हैं और तीनjs भाग पर ध्यान केंद्रित कर सकते हैं।

WawaCoin और WawaCard मॉडल इन-हाउस बनाए गए हैं और स्टार्टर प्रोजेक्ट में उपलब्ध हैं। इस फ्यूचरिस्टिक लुक को बनाने के लिए मैंने drei के MeshTransmissionMaterial का उपयोग किया।

अपनी पसंद के अनुसार दृश्य को बदलने के लिए स्वतंत्र रहें। आप अपने स्वयं के प्रोजेक्ट्स में प्रोजेक्ट के किसी भी भाग का पुनः उपयोग कर सकते हैं।

मैंने भूलवश उल्लेख नहीं किया, लेकिन वेबसाइट की सामग्री केवल काल्पनिक है। मैं कोई नई क्रिप्टोकरेंसी लॉन्च नहीं कर रहा हूँ। (अभी तक? 👀)

कस्टम ट्रेल कर्सर

चलो कर्सर का अनुसरण करने वाला एक साधारण ट्रेल प्रभाव बनाना शुरू करें।

एक नया components/Cursor.jsx फ़ाइल बनाएं और निम्नलिखित कोड जोड़ें:

import { useFrame } from "@react-three/fiber";
import { useControls } from "leva";
import { useRef } from "react";
export const Cursor = () => {
  const { color, intensity, opacity, size } = useControls("Cursor", {
    size: { value: 0.2, min: 0.1, max: 3, step: 0.01 },
    color: "#dfbcff",
    intensity: { value: 4.6, min: 1, max: 10, step: 0.1 },
    opacity: { value: 0.5, min: 0, max: 1, step: 0.01 },
  });
  const target = useRef();
  useFrame(({ clock }) => {
    if (target.current) {
      const elapsed = clock.getElapsedTime();
      target.current.position.x = Math.sin(elapsed) * 5;
      target.current.position.y = Math.cos(elapsed * 2) * 4;
      target.current.position.z = Math.sin(elapsed * 4) * 10;
    }
  });
  return (
    <>
      <group ref={target}>
        <mesh>
          <sphereGeometry args={[size / 2, 32, 32]} />
          <meshStandardMaterial
            color={color}
            transparent
            opacity={opacity}
            emissive={color}
            emissiveIntensity={intensity}
          />
        </mesh>
      </group>
    </>
  );
};

यह एक साधारण गोला है जो एक साइन तरंग का अनुसरण करता है। आप Leva controls का उपयोग करके कर्सर के आकार, रंग, तीव्रता और अपारदर्शिता को समायोजित कर सकते हैं।

अभी के लिए हम एक स्थिर आंदोलन का उपयोग कर रहे हैं, यह ट्रेल के दृश्यता को सरल करेगा। हम इसे बाद में माउस की स्थिति से बदल देंगे।

Cursor घटक को Experience घटक में जोड़ें:

// ...
import { Cursor } from "./Cursor";

export const Experience = () => {
  // ...
  return (
    <>
      <Cursor />
      {/* ... */}
    </>
  );
};

// ...

हम एक चलते हुए गोले को देख सकते हैं, यह हमारे ट्रेल का लक्ष्य होगा।

SimpleTrail कॉम्पोनेंट

group वह टार्गेट है जिसका अनुसरण हमारा trail करेगा। हम trail प्रभाव बनाने के लिए components/SimpleTrail.jsx नामक एक नया कॉम्पोनेंट बनाएंगे:

import { useRef } from "react";
import * as THREE from "three";

export function SimpleTrail({
  target = null,
  color = "#ffffff",
  intensity = 6,
  numPoints = 20,
  height = 0.42,
  minDistance = 0.1,
  opacity = 0.5,
  duration = 20,
}) {
  const mesh = useRef();

  return (
    <>
      <mesh ref={mesh}>
        <planeGeometry args={[1, 1, 1, numPoints - 1]} />
        <meshBasicMaterial
          color={color}
          side={THREE.DoubleSide}
          transparent={true}
          opacity={opacity}
          depthWrite={false}
        />
      </mesh>
    </>
  );
}

पैरामीटर्स निम्नलिखित हैं:

  • target: अनुकरण करने वाला टार्गेट का ref
  • color: trail का रंग।
  • intensity: trail की emissive तीव्रता।
  • numPoints: trail में संग्रहित स्थिति की संख्या। (संख्या जितनी अधिक होगी, trail उतना ही लंबा होगा)।
  • height: trail की ऊँचाई।
  • minDistance: दो बिंदुओं के बीच की न्यूनतम दूरी।
  • opacity: trail की अस्पष्टता।
  • duration: समय जब तक trail अपने अंत से फीका होना शुरू होता है।

चिंता मत करो अगर आप अभी सभी पैरामीटर्स को नहीं समझते हैं। हम इन्हें समझाएंगे जब हम trail को कार्यान्वित करेंगे।

Cursor कॉम्पोनेंट में SimpleTrail कॉम्पोनेंट इंपोर्ट करें:

// ...
import { SimpleTrail } from "./SimpleTrail";

export const Cursor = () => {
  // ...

  return (
    <>
      <group ref={target}>{/* ... */}</group>
      <SimpleTrail
        target={target}
        color={color}
        intensity={intensity}
        opacity={opacity}
        height={size}
      />
    </>
  );
};

mesh एक <planeGeometry /> से बना हुआ है जिसमें numPoints के बराबर सेगमेंट होते हैं। हम टार्गेट का अनुसरण करने के लिए प्रत्येक सेगमेंट की स्थिति को अपडेट करेंगे।

SimpleTrail

दृश्य रूप में क्योंकि हमारे plane का आकार 1x1 है, हम एक वर्ग देख सकते हैं, लेकिन सेगमेंट की संख्या की वजह से, हम वर्टिसेस को नियंत्रित करने में सक्षम होंगे ताकि trail प्रभाव बना सके।

चलिए समानांतर में एक plane को एक सेगमेंट के साथ और एक plane को 20 सेगमेंट्स के साथ देखते हैं:

<group position-x={5}>
  <mesh position-x={4} scale-y={5}>
    <planeGeometry args={[1, 1, 1, numPoints - 1]} />
    <meshBasicMaterial color={"red"} wireframe />
  </mesh>
  <mesh position-x={2} scale-y={5}>
    <planeGeometry args={[1, 1, 1, 1]} />
    <meshBasicMaterial color={"red"} wireframe />
  </mesh>
</group>

यह कोड केवल दृश्यता उद्देश्यों के लिए है। आप इस अवधारणा को समझने के बाद इसे हटा सकते हैं।

हम उन्हें y-axis पर स्केल करते हैं ताकि सेगमेंट की संख्या के अंतर को देख सकें।

सेगमेंट का प्रतिनिधित्व

आप देख सकते हैं कि बायीं ओर का plane केवल 4 vertices है जबकि दायीं ओर के plane में बहुत अधिक हैं। हम इन vertices को नियंत्रित करेंगे ताकि trail प्रभाव तैयार कर सकें।

हम trail बनाने के लिए line का उपयोग कर सकते थे, लेकिन plane का उपयोग करके हम एक दिलचस्प प्रभाव बना सकते हैं (उदाहरण के लिए हवा के लिए बेहतर काम करता है)।

drei का Trail कॉम्पोनेंट एक line का उपयोग करता है, हम वही चीज़ को फिर से कोड नहीं करना चाहते।

वर्टिसेस को मैनिपुलेट करना

हम समय के साथ लक्षित वस्तु का पीछा करते हुए प्लेन के वर्टिसेस की स्थिति को अपडेट करेंगे।

पहले हमें लक्ष्य की सभी स्थितियों को एक सूची में संग्रहीत करने की आवश्यकता होगी। हम स्थिति स्टोर करने के लिए एक ref का उपयोग करेंगे।

// ...
import * as THREE from "three";

export function SimpleTrail(
  {
    // ...
  }
) {
  const mesh = useRef();
  const positions = useRef(
    new Array(numPoints).fill(new THREE.Vector3(0, 0, 0))
  );
  // ...
}

यह सूची हमेशा numPoints की लंबाई की होगी और लक्ष्य की स्थितियों को संग्रहीत करेगी।

जब लक्ष्य चलता है, तो हम सूची के सामने नई स्थिति जोड़ेंगे, पिछली स्थितियों को पीछे धकेलते हुए।

स्थिति सूची को समझाते हुए ग्राफ

इसे लागू करने के लिए, हम useFrame हुक का उपयोग करेंगे ताकि वर्टिसेस की स्थिति को अपडेट कर सकें।

// ...
import { useFrame } from "@react-three/fiber";

export function SimpleTrail(
  {
    // ...
  }
) {
  // ...

  useFrame(() => {
    if (!mesh.current || !target?.current) {
      return;
    }

    const curPoint = target.current.position;
    const lastPoint = positions.current[0];

    const distanceToLastPoint = lastPoint.distanceTo(target.current.position);

    if (distanceToLastPoint > minDistance) {
      positions.current.unshift(curPoint.clone());
      positions.current.pop();
    }
  });

  // ...
}

पहले हम आखिरी बिंदु और वर्तमान बिंदु के बीच की दूरी की गणना करते हैं। यदि दूरी minDistance से अधिक है, तो हम वर्तमान बिंदु को unshift के माध्यम से सूची के आगे जोड़ेंगे और pop के माध्यम से अंतिम बिंदु को हटा देंगे।

अब हमें प्लेन के वर्टिसेस की स्थिति को लक्ष्य की स्थिति का पीछा करने के लिए अपडेट करना होगा।

Three.js logoReact logo

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
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.