आतिशबाजी

Starter pack

स्काई एडवेंचर में आपका स्वागत है, जो आकाशगंगा में सबसे बेहतरीन आतिशबाजी प्रदान करने वाली एक भविष्यवादी कंपनी है! 🎇

हम Three.js, React Three Fiber, और हमारे VFX इंजन का उपयोग करके हमारी आतिशबाजी दिखाने के लिए एक 3D वेबसाइट बनाएंगे।

यह वह है जो हम साथ में बनाएंगे!

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

हमारे स्टार्टर प्रोजेक्ट में पहले से ही निम्नलिखित शामिल हैं:

  • एक बुनियादी React Three Fiber सेटअप जिसमें एक सुंदर तैरता हुआ द्वीप है जहाँ से हम अपनी आतिशबाजी लॉन्च करेंगे।
  • पोस्ट-प्रोसेसिंग इफेक्ट्स जो मॉडल से (और बाद में आतिशबाजी) के लाइट्स को ब्लूम बनाएंगे।
  • एक सरल UI Tailwind CSS के साथ तीन बटन के साथ जो बाद में आतिशबाजी लॉन्च करने के लिए हैं।

तैरता हुआ द्वीप के साथ स्काई एडवेंचर पूर्वावलोकन

यह वही है जो हमें स्टार्टर प्रोजेक्ट चलाने पर मिलता है।

आतिशबाजी

आतिशबाजी बनाने के लिए, हम पिछले पाठ में बने VFX इंजन का उपयोग करेंगे। यह इंजन हमें विभिन्न व्यवहारों के साथ कई पार्टिकल सिस्टम बनाने और प्रबंधित करने की अनुमति देता है।

useFireworks

फायरवर्क्स को कुशलतापूर्वक प्रबंधित करने के लिए, हम useFireworks नामक एक कस्टम hook बनाएंगे। यह hook फायरवर्क्स के निर्माण और प्रबंधन को संभालेगा।

हमारी परियोजना में zustand लाइब्रेरी जोड़ें:

yarn add zustand

अब hooks नामक फ़ोल्डर में एक नया फ़ाइल useFireworks.js बनाएं:

import { create } from "zustand";

const useFireworks = create((set, get) => {
  return {
    fireworks: [],
  };
});

export { useFireworks };

फायरवर्क्स की एक खाली array के साथ एक साधारण स्टोर।

आइए एक फायरवर्क बनाने के लिए एक method जोड़ें:

// ...
import { randFloat, randInt } from "three/src/math/MathUtils.js";

const useFireworks = create((set) => {
  return {
    fireworks: [],
    addFirework: () => {
      set((state) => {
        return {
          fireworks: [
            ...state.fireworks,
            {
              id: `${Date.now()}-${randInt(0, 100)}-${state.fireworks.length}`,
              position: [0, 0, 0],
              velocity: [randFloat(-8, 8), randFloat(5, 10), randFloat(-8, 8)],
              delay: randFloat(0.8, 2),
              color: ["skyblue", "pink"],
            },
          ],
        };
      });
    },
  };
});

// ...

addFirework स्टोर में एक नया फायरवर्क जोड़ देगा जिसमें शामिल हैं:

  • id: React komponent में key के रूप में उपयोग करने के लिए एक अनूठा पहचानकर्ता।
  • position: जहां से फायरवर्क शुरू होगा।
  • velocity: फायरवर्क के फटने से पहले की दिशा और गति।
  • delay: फायरवर्क फटने से पहले का समय।
  • color: फायरवर्क विस्फोट कणों के लिए उपयोग करने के लिए रंगों की array।

अब हम इस hook को हमारे UI के साथ फायरवर्क्स लॉन्च करने के लिए जोड़ सकते हैं।

UI.jsx खोलें और addFirework method को buttons से जोड़ते हैं:

import { useFireworks } from "../hooks/useFireworks";

export const UI = () => {
  const addFirework = useFireworks((state) => state.addFirework);

  return (
    <section className="fixed inset-0 z-10 flex items-center justify-center">
      {/* ... */}
      <div
      // ...
      >
        {/* ... */}
        <div className="flex gap-4">
          <button
            // ..
            onClick={addFirework}
          >
            🎆 Classic
          </button>
          <button
            // ..
            onClick={addFirework}
          >
            💖 Love
          </button>
          <button
            // ..
            onClick={addFirework}
          >
            🌊 Sea
          </button>
        </div>
        {/* ... */}
      </div>
    </section>
  );
};

यह जांचने के लिए कि यह काम करता है या नहीं, आइए एक Fireworks.jsx komponent बनाते हैं। हम अभी के लिए बस फायरवर्क्स को कंसोल में लॉग करेंगे:

import { useFireworks } from "../hooks/useFireworks";

export const Fireworks = () => {
  const fireworks = useFireworks((state) => state.fireworks);

  console.log(fireworks);
};

और इसे Experience komponent में जोड़ते हैं:

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

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

  return (
    <>
      {/* ... */}

      <Float
        speed={0.6}
        rotationIntensity={2}
        position-x={4}
        floatIntensity={2}
      >
        <Fireworks />
        <Gltf src="/models/SkyIsland.glb" />
      </Float>

      {/* ... */}
    </>
  );
};

हम Fireworks komponent को इम्पोर्ट करते हैं और इसे हमारे <Float /> komponent में SkyIsland के बगल में जोड़ते हैं।

Fireworks in the console

जब बटन दबाते हैं, तो हम कंसोल में देख सकते हैं कि फायरवर्क्स को स्टोर में सही ढंग से जोड़ा गया है।

उन्हें दृश्य में प्रदर्शित करने से पहले हमें फायरवर्क्स के lifecycle को संभालना होगा। वर्तमान में, उन्हें जोड़ा जाता है लेकिन कभी हटाया नहीं जाता।

हमारे useFireworks hook में addFirework में, हम एक निश्चित समय के बाद फायरवर्क को हटाने के लिए setTimeout जोड़ सकते हैं।

पहले हमें यह जानना होगा कि फायरवर्क कब उत्पन्न होता है। हम फायरवर्क ऑब्जेक्ट में time प्रॉपर्टी जोड़ सकते हैं:

{
  id: `${Date.now()}-${randInt(0, 100)}-${state.fireworks.length}`,
  // ...
  time: Date.now(),
},

फिर फायरवर्क्स को हटाने के लिए जिसने विस्फोट किया है और फीका पड़ गया है, setTimeout कॉल करें:

addFirework: () => {
  set((state) => {
    // ...
  });
  setTimeout(() => {
    set((state) => ({
      fireworks: state.fireworks.filter(
        (firework) => Date.now() - firework.time < 4000 // Max 2 seconds का delay + Max कणों की lifetime की 2 सेकेण्ड
      ),
    }));
  }, 4000);
},

हम उन फायरवर्क्स को फ़िल्टर करते हैं जिन्हें 4 सेकंड पहले जोड़ा गया था। इस तरह, हम उन फायरवर्क्स को बनाए रखते हैं जो अभी भी सक्रिय हैं।

फ़ायरवर्क्स के लिए आप अंतिम सेटिंग का उपयोग करेंगे उसके अनुसार समय समायोजित करें।

Fireworks in the console

जब बटन दबाते हैं, तो हम कंसोल में देख सकते हैं कि फायरवर्क्स को एक निश्चित समय के बाद सही ढंग से हटा दिया जाता है।

अब हम उस हिस्से में गहराई से जा सकते हैं जिसका आप इंतजार कर रहे थे: दृश्य में फायरवर्क्स बनाना!

VFX इंजन (Wawa VFX)

पिछले पाठ से घटक को कॉपी/पेस्ट करने के लिए नहीं, मैंने VFX इंजन को npm पर एक पैकेज के रूप में प्रकाशित किया: Wawa VFX। इसे चलाकर इंस्टॉल कर सकते हैं:

yarn add wawa-vfx@^1.0.0

@^1.0.0 का उपयोग करके, हम सुनिश्चित करते हैं कि हम हमेशा पैकेज का प्रमुख संस्करण 1 उपयोग करते हैं लेकिन नवीनतम माइनर और पैच संस्करण भी शामिल करते हैं। इस प्रकार, हम नवीनतम विशेषताओं और बग फिक्स का लाभ उठा सकते हैं बिना बदलाव के।

अब हम अपने प्रोजेक्ट में <VFXParticles /> और <VFXEmitter /> उपयोग कर सकते हैं!

अनुभव में, चलिए VFXParticles घटक को दृश्य में जोड़ते हैं:

// ...
import { VFXParticles } from "wawa-vfx";

export const Experience = () => {
  const controls = useRef();

  return (
    <>
      {/* ... */}

      <VFXParticles
        name="firework-particles"
        settings={{
          nbParticles: 100000,
          gravity: [0, -9.8, 0],
          renderMode: "billboard",
          intensity: 3,
        }}
      />

      <EffectComposer>
        <Bloom intensity={1.2} luminanceThreshold={1} mipmapBlur />
      </EffectComposer>
    </>
  );
};

हम VFXParticles घटक को निम्नलिखित सेटिंग्स के साथ जोड़ते हैं:

  • 100000 पार्टिकल्स। जैसा कि जब हम सीमा तक पहुंचते हैं, सबसे पुराने पार्टिकल्स को हटा दिया जाएगा, यह एक समय में एक से अधिक आतिशबाजी के लिए काफी होना चाहिए।
  • पार्टिकल्स पर गुरुत्वाकर्षण को अनुकरण करने के लिए gravity-9.8 पृथ्वी पर गुरुत्वाकर्षण है। (लेकिन रुको हम अंतरिक्ष में हैं! 👀)
  • कैमरा को हमेशा सामना करने के लिए renderMode को billboard में सेट करें।
  • रात के आकाश में चमकाने के लिए पार्टिकल्स की intensity को 3 पर सेट करें।

जहां आप <VFXParticles /> घटक रखते हैं वह बहुत महत्वपूर्ण नहीं है। बस यह सुनिश्चित करें कि यह दृश्य के शीर्ष स्तर पर हो।

और चलिए VFXEmitter घटक को VFXParticles के बगल में जोड़ते हैं ताकि विस्फोट को debug मोड में आकार दिया जा सके और दृश्य नियंत्रणों तक पहुंच हो सके:

// ...
import { VFXEmitter, VFXParticles } from "wawa-vfx";

export const Experience = () => {
  const controls = useRef();

  return (
    <>
      {/* ... */}

      <VFXParticles
        name="firework-particles"
        settings={{
          nbParticles: 100000,
          gravity: [0, -9.8, 0],
          renderMode: "billboard",
          intensity: 3,
        }}
      />
      <VFXEmitter emitter="firework-particles" debug />

      {/* ... */}
    </>
  );
};

सुनिश्चित करें कि emitter प्रॉप को VFXParticles घटक के समान name पर सेट करें और नियंत्रण देखने के लिए debug को true पर सेट करें।

फायरवर्क्स विस्फोट का पहला संस्करण बनाएँ। 💥

एक बार जब आप सेटिंग्स से संतुष्ट हो जाएं, तो आप VFXEmitter घटक से debug प्रॉप को हटा सकते हैं, निर्यात बटन पर क्लिक करें और VFXEmitter घटक में सेटिंग्स चिपकाएं।

<VFXEmitter
  emitter="firework-particles"
  settings={{
    nbParticles: 5000,
    delay: 0,
    spawnMode: "burst",
    colorStart: ["skyblue", "pink"],
    particlesLifetime: [0.1, 2],
    size: [0.01, 0.4],
    startPositionMin: [-0.1, -0.1, -0.1],
    startPositionMax: [0.1, 0.1, 0.1],
    directionMin: [-1, -1, -1],
    directionMax: [1, 1, 1],
    startRotationMin: [degToRad(-90), 0, 0],
    startRotationMax: [degToRad(90), 0, 0],
    rotationSpeedMin: [0, 0, 0],
    rotationSpeedMax: [3, 3, 3],
    speed: [1, 12],
  }}
/>

हमारे पास सब कुछ तैयार है वातश्रोतक को VFX इंजन से जोड़ने के लिए!

आतिशबाज़ी विस्फोट

Fireworks.jsx फाइल के अंदर, आइए एक Firework कॉम्पोनेन्ट बनाएं जो एक आतिशबाज़ी को प्रदर्शित करेगा:

// ...
import { useRef } from "react";
import { VFXEmitter } from "wawa-vfx";

export const Fireworks = () => {
  // ...
};

const Firework = ({ velocity, delay, position, color }) => {
  const ref = useRef();
  return (
    <>
      <group ref={ref} position={position}>
        <VFXEmitter
          emitter="firework-particles"
          settings={{
            nbParticles: 5000,
            delay: 0,
            spawnMode: "burst",
            colorStart: ["skyblue", "pink"],
            particlesLifetime: [0.1, 2],
            size: [0.01, 0.4],
            startPositionMin: [-0.1, -0.1, -0.1],
            startPositionMax: [0.1, 0.1, 0.1],
            directionMin: [-1, -1, -1],
            directionMax: [1, 1, 1],
            startRotationMin: [degToRad(-90), 0, 0],
            startRotationMax: [degToRad(90), 0, 0],
            rotationSpeedMin: [0, 0, 0],
            rotationSpeedMax: [3, 3, 3],
            speed: [1, 12],
          }}
        />
      </group>
    </>
  );
};

बस VFXEmitter को Experience कॉम्पोनेन्ट से काटें/चिपकाएं और Firework कॉम्पोनेन्ट में डालें।

हम इसे <group /> में लपेटते हैं ताकि position और velocity के आधार पर सीन में आतिशबाज़ी को स्थानांतरित किया जा सके।

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.