[Für Anfänger] Einführung in React Three Faser X Drei X TypyScript! Erstellen Sie Pixelkunst und dynamische Animationen aus Bildern

[Für Anfänger] Einführung in React Three Faser X Drei X TypyScript! Erstellen Sie Pixelkunst und dynamische Animationen aus Bildern

In jüngster Zeit hat die Entwicklung von Webanwendungen immer mehr Anstrengungen unternommen, um die Benutzererfahrung mithilfe von Grafiken zu verbessern. Mit React Three Fiber (R3F) können Sie problemlos drei.Js -Funktionen als React -Komponente verwenden, was es jedem leicht macht, attraktive Ausdrücke zu erreichen.

erläutern wir ausführlich, wie Sie die Wrapper -Bibliothek DREI und TypeScript kombinieren und Pixel -Kunst , die automatisch aus den Bildern generiert werden

📌 Darüber hinaus wird diese Implementierung keine speziellen 3D -Modelle verwendet und nur die von drei standardmäßige Grundgeometrie (Box, Ebene usw.) bereitgestellte Basisgeometrie verwendet, um Retro -und dennoch anspruchsvolle Ausdrücke zu erstellen, die für Pixel -Kunst einzigartig sind.
Die Schritt-für-Schritt-Erklärungen sind auch für Anfänger leicht zu verstehen, und der Inhalt ist so, dass Sie lernen können, während Sie tatsächlich an Ihren Händen arbeiten. Probieren Sie es also aus!

💡 Abgeschlossenes Bild

📺 Sehen Sie sich die Demo auf YouTube an : Sie können sie aus diesem Link

Wir werden in Zukunft weiterhin Lektionen und Arbeiten von TypeScript X reagieren.
Wir werden eine Ankündigung auf YouTube machen. Abonnieren Sie also unseren YouTube -Kanal und warten Sie auf Benachrichtigungen!

📺 YouTube ansehen : Sie können es von diesem Link

Wenn Sie wissen möchten, was Reagieren von drei Fasern tun können, beziehen Sie sich bitte Folgendes!
Wir haben benutzerfreundliche Arbeiten zur Verfügung!

Inhaltsverzeichnis

🚀Inführung in technische Elemente: Tools und Bibliotheken, die in diesem Projekt verwendet werden können

Sie können die Tools und Bibliotheken ändern, die Sie verwenden, die für sich selbst einfach zu bedienen sind, aber dieses Projekt erklärt diese Annahme.

VSCODE
  • Ein kostenloser Code -Editor von Microsoft.
  • Es muss kein VSCODE sein, aber es gibt viele Erweiterungen, also empfehle ich es.
  • Es wird auch empfohlen, Eslint oder hübscher einzuschließen.
Node.js
  • Eine JavaScript , die auf Chrome's V8 JavaScript Engine basiert .
  • Sie können JavaScript -Code außerhalb Ihres Browsers ausführen.
  • Dies wird auf der Grundlage der Annahme erklärt, dass es bereits installiert ist. Bitte laden Sie es also von
    https://nodejs.org/ja *Wir empfehlen, die langfristige stabile Version von LTS herunterzuladen.
Vite
  • Ein Build -Tool für moderne Webprojekte. Es ist durch seine schnelle und leichte
  • Die zuvor verwendete "CRA (Create-React-App)" ist nicht auf der offiziellen Website aufgeführt und ist zu einer alten Technologie geworden.
  • Von nun an sollte Vite die beste Option beim Erstellen von Apps mit React sein.
Reagieren
  • Dies ist eine JavaScript -Bibliothek zum Erstellen einer Benutzeroberfläche (Benutzeroberfläche). Es wurde von Facebook entwickelt und wird heute noch in vielen Web -Apps verwendet.
Drei.js
  • Eine JavaScript -Bibliothek zum einfachen Erstellen von 3D -Grafiken. Es wird die komplexen Operationen von WebGL abstrahiert und die intuitive 3D -Entwicklung ermöglicht.
  • Es ist einfach, 3D -Grafiken zu erstellen und einfacher zu verwenden als direkte WebGL -Operationen.
Reagieren Sie drei Faser
  • Dies ist eine Bibliothek, in der drei.js mit React verwendet werden können. Es kombiniert die Komponentenstruktur von React mit drei.js 3D -Motor.
  • Drei.Js können im React -Entwicklungsstil verwendet werden, was eine intuitive und effiziente Entwicklung ermöglicht.
Reagieren Sie drei Drei
  • Eine Sammlung nützlicher Nutzkomponenten für React Three Faser. Es ist einfach, die häufig verwendeten drei.js -Funktionen hinzuzufügen.
  • Komplexe drei.js -Funktionen können mit kurzem Code erreicht werden, wodurch die Lernkosten gesenkt werden.

🚀 Machen Sie "Pixelkunst" mit drei Faser × DREI × Typscript!

📌Die Umweltkonstruktion wird in diesem Artikel

📌Diese Zeit verwenden wir keine speziellen 3D -Modelle, sondern nur Standardobjekte, die in React Three Faser erhältlich sind und drei DREI reagieren.
Wenn Sie mehr über Standardobjekte erfahren möchten, lesen Sie bitte auch diesen Artikel

Bitte überprüfen Sie GitHub für den vollständigen Quellcode, den Sie dieses Mal erstellt haben.

💾 GitHub Repository : Überprüfen Sie den Quellcode unter diesem Link

💡Created die Benutzeroberfläche für das Bedienfeld !!

Zunächst erstellt das Bedienfeld eine Benutzeroberfläche, damit Benutzer Bilder hochladen, Pixelgrößen festlegen und verschiedene Animationen betreiben können.

// React und drei.js -bezogene Bibliotheken importieren {usestate} aus "react"; // Konstante Einstellung: const default_pixel_size = 64; //. ussten<number> (Default_pixel_size); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular Return (<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div className="absolute top-4 left-4 bg-white shadow-lg p-4 rounded-lg z-10 w-64 space-y-4"> {/ * Bilddatei */} auswählen <input type="file" accept="image/*" className="w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" /> {/ * Pixelgrößeneingangsfeld */}<div className="flex items-center space-x-2"> <label className="text-sm text-gray-700">Pixelgröße:</label><input type="number" value={tempPixelSize} onChange={(e) => settemppixelSize (number (e.target.Value))} min = "1" max = "128" classname = "w-16 Border Border-Gray-300 Rounded-2 Py-1 Text-SM Fokus: Ring-2 Fokus: Ring-Blue-500 Fokus: SUCKLINE-NONE" /></div> {/ * Redisplay -Schaltfläche */} <button className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition">Redisplay</button> {/ * Animation Control Button */}<div className="flex flex-wrap gap-2"><button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition">Explosionswelle</button><button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition">​</button></div></div></div> ); }; Standard -Standard -App exportieren;

Dieses Mal möchte ich etwas Einfaches schaffen, also lasse ich es so als Benutzeroberfläche.
Explosion und Welle werden verwendet, um Pixelkunst zu animieren.
Ich denke, der Vorteil des Erstellens von Pixelkunst mit React Three Faser besteht darin, dass Sie Pixelkunst Animation hinzufügen können.

💡create ein Bedienfeldereignis !!

Ich werde das Ereignis in die Benutzeroberfläche einbringen, die ich gerade erstellt habe.

Handlinge

HandleChange ist der Vorgang, wenn ein Bild ausgewählt wird.
Durch die Auswahl eines Bildes aktualisiert die Pixelgröße und dann die Bildquelle.

// React und drei.js -bezogene Bibliotheken importieren {usestate} aus "react"; // Konstante Einstellung: const default_pixel_size = 64; //. ussten<number> (Default_pixel_size); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [pixelSize, setpixelSize] = Usestate<number> (temppixelSize); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [ImagesRC, setImagesrc] = Usestate<string | null> (NULL); // - ImagesRC: Daten -URL des importierten Bildes // ---- // Was ist zu tun, wenn eine Bilddatei ausgewählt wird: // - Laden Sie die Datei auf, konvertieren Sie sie in eine Daten -URL und setzen Sie sie in ImagesRC //. ---------------------------------------------------------------------------------------------------------------------------------------------------------<HTMLInputElement> ) => {const File = e.target.files?. [0]; if (! file) return; const reader = new fileReader (); reader.onload = (ev) => {const url = ev.target?.result; if (typeof url! == "String") zurück; // Aktualisieren Sie die Pixelgröße und setzen Sie dann das Bildquellen -SetpixelSize (temppixelSize). setImagesRC (URL); }; Reader.ReadasDataurl (Datei); }; zurückkehren (<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div className="absolute top-4 left-4 bg-white shadow-lg p-4 rounded-lg z-10 w-64 space-y-4"> {/ * Bilddatei */} auswählen <input type="file" accept="image/*" onChange={handleFileChange} className="w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" /> {/ * Pixelgrößeneingangsfeld */} ...</div></div> ); }; Standard -Standard -App exportieren;

neu loadimage

Als nächstes kommt das Redisplay -Button -Event.
Dies wird verwendet, wenn die Pixelgröße und die Wiederaufnahme der Pixelgröße aktualisiert werden.
Dies ist eine Form, die TemppixelSize in PixelSize widerspiegelt.

// React und drei.js -bezogene Bibliotheken importieren {usestate} aus "react"; // Konstante Einstellung: const default_pixel_size = 64; //. ussten<number> (Default_pixel_size); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [pixelSize, setpixelSize] = Usestate<number> (temppixelSize); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [ImagesRC, setImagesrc] = Usestate<string | null> (NULL); // - ImagesRC: Daten -URL des importierten Bildes // ---- // Was ist zu tun, wenn eine Bilddatei ausgewählt wird: // - Laden Sie die Datei auf, konvertieren Sie sie in eine Daten -URL und setzen Sie sie in ImagesRC //. ---------------------------------------------------------------------------------------------------------------------------------------------------------<HTMLInputElement> ) => {...}; // ------ // Verarbeitung beim Drücken der Schaltfläche "Überprüfung": //-das Bild neu zeichnen, indem Sie den Wert von temppixelSize in PixelSize reflektieren // ---------------------------------------------------------------------------------------------------------------------------------------------------------<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div className="absolute top-4 left-4 bg-white shadow-lg p-4 rounded-lg z-10 w-64 space-y-4"> ... {/ * Redisplay -Schaltfläche */} <button className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition" onClick={reloadImage} >Redisplay</button> {/ * Animation Control Button */}<div className="flex flex-wrap gap-2"><button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition">Explosionswelle</button><button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition">​</button></div></div></div> ); }; Standard -Standard -App exportieren;

ControlExplosionanimation und Controlwaveanimation

Das Ereignis zur Animation Control -Taste sieht so aus:
Da ich Animation_Time als Konstante festgelegt habe, werde ich in dieser Anzahl von Sekunden, in der gleichen Anzahl von Sekunden zurückkehren und in den Standardmodus zurückkehren.

// React und drei.JS-bezogene Bibliotheken importieren {usestate} aus "react"; // Konstante Einstellung: const default_pixel_size = 64; // - default_pixel_size: Standardgröße (in Pixel) beim Verkleinern des Bildkonstants Animation_Time = 3; // - Animation_Time: Zeit (in Sekunden) zur Animation // ===== // App -Komponenten: // - Zentrales UI -Management (Bildladen, Pixel -Größe, Animationsoperationen) // - ordnen Sie 2 Canvas an (Pixel -Szene und Hintergrundszene) // ====== const Applp = () => {// State Management: const.<number> (Default_pixel_size); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [pixelSize, setpixelSize] = Usestate<number> (temppixelSize); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [ImagesRC, setImagesrc] = Usestate<string | null> (NULL); // - ImagesRC: Daten -URL des importierten Bilds const [Animation, SetAnimation] = Usestate ("Standard"); // - Animation: Aktueller Animationsmodus // ---- // Was tun, wenn eine Bilddatei ausgewählt wird: // - Laden Sie die Datei auf, konvertieren Sie sie in eine Daten -URL und setzen Sie sie in ImagesRC // ein ---------------------------------------------------------------------------------------------------------------------------------------------------------<HTMLInputElement> ) => {...}; // ------ // Verarbeitung beim Drücken der Schaltfläche "rezensionieren": //-das Bild reflektiert, indem der Wert von temppixelSize in PixelSize // reflektiert wird // --------------------------------------------------------------------------------------------------------------------------------------------------------- Animationskontrolle: // - Start, Ende und rückgängig machen die Explosion nacheinander mit Timeout // ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- setAnimation ("Standard"); }, Animation_time * 2000); }; // ------ // Wellenanimation steuern: //-Starten, Ende und Rückgängigungen nacheinander Timeout // führen --------------------------------------------------------------------------------------------------------------------------------------------------------- setAnimation ("wave_end"); }, Animation_time * 1000); setTimeout (() => {setAnimation ("Standard");}, Animation_time * 2000); }; zurückkehren (<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div className="absolute top-4 left-4 bg-white shadow-lg p-4 rounded-lg z-10 w-64 space-y-4"> ... {/ * Animation Control Taste */}<div className="flex flex-wrap gap-2"> <button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition" onClick={controlExplosionAnimation} >Explosionswelle</button> <button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition" onClick={controlWaveAnimation} >​</button></div></div></div> ); }; Standard -Standard -App exportieren;

💡Die aktuelle Gesamtquelle ist hier

// React und drei.JS-bezogene Bibliotheken importieren {usestate} aus "react"; // Konstante Einstellung: const default_pixel_size = 64; // - default_pixel_size: Standardgröße (in Pixel) beim Verkleinern des Bildkonstants Animation_Time = 3; // - Animation_Time: Zeit (in Sekunden) zur Animation // ===== // App -Komponenten: // - Zentrales UI -Management (Bildladen, Pixel -Größe, Animationsoperationen) // - ordnen Sie 2 Canvas an (Pixel -Szene und Hintergrundszene) // ====== const Applp = () => {// State Management: const.<number> (Default_pixel_size); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [pixelSize, setpixelSize] = Usestate<number> (temppixelSize); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [ImagesRC, setImagesrc] = Usestate<string | null> (NULL); // - ImagesRC: Daten -URL des importierten Bilds const [Animation, SetAnimation] = Usestate ("Standard"); // - Animation: Aktueller Animationsmodus // ---- // Was tun, wenn eine Bilddatei ausgewählt wird: // - Laden Sie die Datei auf, konvertieren Sie sie in eine Daten -URL und setzen Sie sie in ImagesRC // ein ---------------------------------------------------------------------------------------------------------------------------------------------------------<HTMLInputElement> ) => {const File = e.target.files?. [0]; if (! file) return; const reader = new fileReader (); reader.onload = (ev) => {const url = ev.target?.result; if (typeof url! == "String") zurück; // Die Pixelgröße einmal aktualisieren und dann die Bildquelle setpixelSize (temppixelSize) festlegen. setImagesRC (URL); }; Reader.ReadasDataurl (Datei); }; // ------ // Aktion beim Drücken der Schaltfläche "Rezension": //-das Bild neu zeichnen, indem Sie den Wert von temppixelSize in PixelSize reflektieren // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---- // Wellenanimationskontrolle: //-Start, Ende und rückgängig bei Timeout //. ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- => {setAnimation ("Standard"); }, Animation_time * 2000); }; zurückkehren (<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div className="absolute top-4 left-4 bg-white shadow-lg p-4 rounded-lg z-10 w-64 space-y-4"> {/ * Bilddatei */} auswählen <input type="file" accept="image/*" onChange={handleFileChange} className="w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" /> {/ * Pixelgrößeneingangsfeld */}<div className="flex items-center space-x-2"> <label className="text-sm text-gray-700">Pixelgröße:</label><input type="number" value={tempPixelSize} onChange={(e) => settemppixelSize (number (e.target.Value))} min = "1" max = "128" classname = "w-16 Border Border-Gray-300 Rounded-2 Py-1 Text-SM Fokus: Ring-2 Fokus: Ring-Blue-500 Fokus: SUCKLINE-NONE" /></div> {/ * Redisplay -Schaltfläche */} <button className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition" onClick={reloadImage} >Redisplay</button> {/ * Animation Control Button */}<div className="flex flex-wrap gap-2"> <button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition" onClick={controlExplosionAnimation} >Explosionswelle</button> <button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition" onClick={controlWaveAnimation} >​</button></div></div></div> ); }; Standard -Standard -App exportieren;

💡 Pixeldaten aus Bildern erstellen !!

Dieses Mal laden wir das Bild, generieren die Pixeldaten und zeigen den Bildschirm an.
Erstellen wir also einen Prozess, der Pixeldaten aus einem Bild generiert.

*Für die Erläuterung sind Dateien usw. nicht getrennt. Ich denke, es wäre besser, Dateien auf der Komponentenebene zu trennen, um lesbarer zu sein.

Erstellen einer CreatePixeldata -Funktion

// React und drei.JS-bezogene Bibliotheken importieren {usestate} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Position (x, y, z) und Farbe (drei.Color) jedes Pixels // ----------------------------------------------------------------------------------------------------------------------------------------------------- X: Zahl; Y: Zahl; Z: Nummer; Farbe: Drei.Color; }; // Konstante Einstellung: const default_pixel_size = 64; // - default_pixel_size: Standardgröße (in Pixel) beim Verkleinern des Bildkonstants Animation_Time = 3; // - Animation_time: Zeit für Animation (Sekunden) // ====== // App -Komponenten: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - arrangieren Sie zwei Leinwand (Pixel -Szene und Hintergrundszene) // ===== konstest App = () => {...}; Standard -Standard -App exportieren; // ===== // / createPixelData function: // - Get pixel data from the specified image using Canvas and convert it to an array of type PixelInfo // ===== const createPixelData = ( img: HTMLImageElement, targetWidth: number, targetHeight: number ): PixelInfo[] => { // Create a Canvas element and set es zur angegebenen Größe const canvas = document.createelement ("canvas"); canvas.width = targetwidth; Canvas.Height = Taretheight; const ctx = canvas.getContext ("2d"); if (! ctx) werfen einen neuen Fehler ("Nr. 2D -Kontext verfügbar"); // Zeichnen Sie ein Bild auf Leinwand und erhalten Sie Pixelinformationen ctx.drawimage (IMG, 0, 0, Targetwidth, Taretheight); const imgdata = ctx.getImagedata (0, 0, targetwidth, targeeteight); const data = imgdata.data; const Ergebnis: pixelinfo [] = []; lass idx = 0; // für jedes Pixel im Bild den RGBA -Wert abrufen und in Pixelinfo für (sei y = 0; y <taretheight; y ++) {für (let x = 0; x <targetWidth; x ++) {const r = data [idx], g = daten [idx+1], b = data [idx+2], a = Data [idx+3]; IDX += 4; // Pixel mit niedriger Transparenz (wenn a <30) ignorieren, wenn (a <30) fortgesetzt wird; result.push ({// x, y -Koordinaten so, dass die Bildmitte der Ursprung x: x - Zielbreite / 2, y: -y + taretheight / 2, z: 0, // Erstellen Sie drei. }} Rückgabeergebnis; };

Der Prozess ist wie folgt: Der Prozess ist etwas kompliziert, aber ich denke, was ich tue, ist einfach.

  • Holen Sie sich das Bild und die Pixelgröße
  • Zeichnen Sie das Bild auf Leinwand, um Pixelinformationen zu erhalten
  • Erhält RGBA -Informationen für Pixel und speichert sie in Pixelinfo

Erstellen Sie einen Anrufteil (UseEffect)

Da Pixeldaten bei ändert, wenn sich das Bild oder die Pixelgröße ändert, verwenden Sie Effect (), um [PixelSize, ImagesRC] zu überwachen.

// React und drei.JS-bezogene Bibliotheken importieren {usestate, useEffect} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Verwalten Sie die Position (x, y, z) und Farbe (drei.Color) jedes Pixels // --------------------------------------------------------------------------------------------------------------------------------------------------------- X: Zahl; Y: Zahl; Z: Nummer; Farbe: Drei.Color; }; // Konstante Einstellung: const default_pixel_size = 64; // - default_pixel_size: Standardgröße (in Pixel) beim Verkleinern des Bildkonstants Animation_Time = 3; // - Animation_time: Zeit für Animation (Sekunden) // ====== // App -Komponenten: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsoperationen) // - platzieren Sie zwei Leinwand (Pixel -Szene und Hintergrundszene) // ======= const app = () => {// State Management: const: const: const [pixel [pixels), setpixel<PixelInfo[] | null> (NULL); // - Pixel: Array von Pixelinformationen, die aus dem Bild const [filechangeCount, setFilechangeCount] = Usestate generiert wurden<number> (0); // - filechangeCount: Anzahl der Änderungen am Bild (zum Auslösen einer Reloade<number> (Default_pixel_size); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [pixelSize, setpixelSize] = Usestate<number> (temppixelSize); // - temppixelSize: Temporäre Pixelgröße auf Eingangsformular const [ImagesRC, setImagesrc] = Usestate<string | null> (NULL); // - ImagesRC: Daten -URL des importierten Bilds const [Animation, SetAnimation] = Usestate ("Standard"); //-Animation: Aktueller Animationsmodus ... // ---- // Pixeldaten aus dem Bild generieren, wenn sich das Bild oder das Pixel-Versimse ändert // --------------------------------------------------------------------------------------------------------------------------------------------------------- Trigger, wenn das Bild ändert setFilechangeCount ((prev) => pre + 1); // neues Bild laden und Pixeldaten mit Onload -Ereignis const img = new Image () generieren; img.onload = () => {const pixel = createpixeldata (IMG, pixelSize, pixelSize); setpixel (pix); }; img.src = imagesRC; }, [pixelSize, ImagesRC]); zurückkehren (<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------</div> ); }; Standard -Standard -App exportieren; // ==== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo umwandeln die angegebene Größe const canvas = document.createelement ("canvas"); canvas.width = targetwidth; Canvas.Height = Taretheight; const ctx = canvas.getContext ("2d"); if (! ctx) werfen einen neuen Fehler ("Nr. 2D -Kontext verfügbar"); // das Bild auf Leinwand zeichne und Pixelinformationen ctx.drawimage (IMG, 0, 0, Targetwidth, Taretheight) erhalten; const imgdata = ctx.getImagedata (0, 0, targetwidth, targeeteight); const data = imgdata.data; const Ergebnis: pixelinfo [] = []; lass idx = 0; // für jedes Pixel im Bild den RGBA -Wert abrufen und in Pixelinfo für (sei y = 0; y <taretheight; y ++) {für (let x = 0; x <targetWidth; x ++) {const r = data [idx], g = daten [idx+1], b = data [idx+2], a = Data [idx+3]; IDX += 4; // Pixel mit niedriger Transparenz (a <30) ignorieren, wenn (a <30) fortgesetzt wird; result.push ({// x, y koordinaten, so dass die Bildmitte der Ursprung x: x - targetwidth / 2, y: -y + taretheight / 2, z: 0, // Erstellen Sie drei. }} Rückgabeergebnis; };

💡A Canvas ist für Pixel Display erhältlich !!

Geben Sie zunächst die Leinwand und bereiten Sie Ihre Kamera, Beleuchtung usw. vor

// React und drei.JS-bezogene Bibliotheken importieren {OrbitControls} aus "@react-three/drei"; importieren {canvas} aus "@react-drei/faser"; importieren {usustate, useEffect, useref} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Verwalten Sie die Position (x, y, z) und Farbe (drei.Color) jedes Pixels // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Zeit, die in Sekunden bis zur Animation dauert // ==== // App -Komponenten: // - Zentrales UI -Management (Bildladung, Pixelgrößen, Animationsvorgänge) // - ordnen Sie zwei Leinwand (Pixel -Szene und Hintergrundszene) an // ===== konstest App = () => {... zurück (return (return (return<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Pixelgrid nur dann rendern, wenn Pixeldaten vorhanden sind */})}</Canvas></div></div> ); }; Standard -Standard -App exportieren; // ==== // createPixelData function: // - Get pixel data from the specified image using Canvas and convert it to an array of type PixelInfo // ===== const createPixelData = ( img: HTMLImageElement, targetWidth: number, targetHeight: number ): PixelInfo[] => { ... return result; };

💡 Pixel anzeigen !!

// React und drei.JS-bezogene Bibliotheken importieren {OrbitControls} aus "@react-three/drei"; importieren {canvas} aus "@react-drei/faser"; importieren {usustate, useEffect, useref} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Verwalten Sie die Position (x, y, z) und Farbe (drei.Color) jedes Pixels // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Zeit, die in Sekunden bis zur Animation in Animation benötigt wird // ==== // PixelGrid -Komponente: // - Rendern Gruppen von Pixeldaten und steuert Animation (schrittweise Vergrößerung) und bewegte Animation (Explosion/Welle) // ==== Typ PixelgridProps = {Pixelsize: number; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({pixelsize, pixel, Animation, filechangeCount,}: pixelgridProps) => {// Ein Verweis auf das Gruppenobjekt in drei.js. Wird verwendet, um alle Pixel const GroupRef = Useref zu gruppieren<THREE.Group> (NULL); // platziere jede Pixelbox -Komponente in einer Gruppe, die von GroupRef verwaltet wurde, um die Rückkehr zu rendern (<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={1} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - ordnen<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Render pixelgrid nur, wenn Pixeldaten vorhanden sind */} {Pixels && ( <PixelGrid pixelSize={pixelSize} pixels={pixels} animation={animation} fileChangeCount={fileChangeCount} /> )}</Canvas></div></div> ); }; Standard -Standard -App exportieren; // ===== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo konvertieren // ===== const createpixeldata = (img: htmlimageElement, targetWidth: number, tarnethight: nummer: pixelinfo [] {{{};

Ich denke, die Pixelkunst wird auf diese Weise angezeigt.
Das ist in Ordnung, aber da ich es mit React Three Faser mache, werde ich Animationen hinzufügen und mehr.

💡 Anzeigeanimation hinzugefügt

Ich werde versuchen, die Display -Animation nach und nach nachzubilden, wenn sie allmählich gezogen wird.
Es handelt sich um ein Bild, das die Pixelskala allmählich von 0 bis 1 erhöht.

// React und drei.JS-bezogene Bibliotheken importieren {OrbitControls} aus "@react-three/drei"; importieren {canvas, useFrame} aus "@react-three/faser"; importieren {usustate, useEffect, useref} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Position jedes Pixels (x, y, z) und Farbe (drei.Color) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Animation_Time: Zeit (in Sekunden) zur Animation // ==== // Pixelgrid -Komponente: // - Renders Gruppen von Pixeldaten und steuert die Anzeige von Animation (allmähliche Vergrößerung) und bewegte Animation (Explosion/Wave) // === Typ PixelGridProps = {{Pixelsize: Nummer; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({pixelsize, pixel, Animation, filechangeCount,}: pixelgridProps) => {// Ein Verweis auf das Gruppenobjekt in drei.js. Wird verwendet, um alle Pixel const GroupRef = Useref zu gruppieren<THREE.Group> (NULL); //-<number[]> (Array (pixels.length) .Fill (0)); // scaleProgressRef: Halten Sie den Anzeigefortschritt (akkumulierte Zeit) für jede Batch const ScaleProgressRef = Useref (0); // batchIndexref: verwaltet die aktuell angezeigte Stapelnummer const batchIndexref = useref (0); // Verwenden Sie den Rahmen und Anzeigen von Pixeln Schritt für Schritt verwenden Sie. const threshold = batchIndexref.current * (Animation_Time / (Pixel.Length / PixelSize)); Zugehörigkeit zum aktuellen Batch -Startindex = Batchindexref.Current * Pixelsize; Fahren Sie mit dem nächsten Batch -BatchIndexRef. -Aktueller += 1;}}); // platziere jede Pixelbox -Komponente in einer von GroupRef verwalteten Gruppe und rendere sie (rendere sie<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={scales[i]} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - ordnen<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Render pixelgrid nur, wenn Pixeldaten vorhanden sind */} {Pixels && ( <PixelGrid pixelSize={pixelSize} pixels={pixels} animation={animation} fileChangeCount={fileChangeCount} /> )}</Canvas></div></div> ); }; Standard -Standard -App exportieren; // ===== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo konvertieren // ===== const createpixeldata = (img: htmlimageElement, targetWidth: number, tarnethight: nummer: pixelinfo [] {{{};

💡 Unterstützt das Image Reloading !!

In diesem Fall funktioniert die Anzeigeanimation nicht, wenn das Bild neu geladen wird und sofort angezeigt wird.
Fügen Sie UseEffect hinzu, um den Status zurückzusetzen, wenn Sie ein Bild neu laden oder die Pixelgröße ändern.

// React und drei.JS-bezogene Bibliotheken importieren {OrbitControls} aus "@react-three/drei"; importieren {canvas, useFrame} aus "@react-three/faser"; importieren {usustate, useEffect, useref} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Position jedes Pixels (x, y, z) und Farbe (drei.Color) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Animation_Time: Zeit (in Sekunden) zur Animation // ==== // Pixelgrid -Komponente: // - Renders Gruppen von Pixeldaten und steuert die Anzeige von Animation (allmähliche Vergrößerung) und bewegte Animation (Explosion/Wave) // === Typ PixelGridProps = {{Pixelsize: Nummer; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({pixelsize, pixel, Animation, filechangeCount,}: pixelgridProps) => {// Ein Verweis auf das Gruppenobjekt in drei.js. Wird verwendet, um alle Pixel const GroupRef = Useref zu gruppieren<THREE.Group> (NULL); //-<number[]> (Array (pixels.length) .Fill (0)); // scaleProgressRef: Halten Sie den Anzeigefortschritt (akkumulierte Zeit) für jede Batch const ScaleProgressRef = Useref (0); // batchIndexref: verwaltet die aktuell angezeigte Stapelnummer const batchIndexref = useref (0); // eine Referenz, um festzustellen, ob eine Bilddatei geändert wurde. Const PrevFilechangeCountref = Useref (filechangeCount); // setzt den Anzeigezustand (Skala) aller Pixel beim Nachladen eines BildsEffect (() => {if (fileChoneCount! scaleProgressRef.Current = 0; // Verwenden Sie den Namen, um jeden Frame zu aktualisieren und Pixel Schritt für Schritt verwenden. // Zeit hinzufügen, da der vorherige Frame ScaleProgressRef.Current += Delta; // Berechnen Sie den Zeitschwellenwert, um den aktuellen Batch const Threshold = batchIndexref.current * (Animation_time / (pixels.length / pixelSize)) anzuzeigen; // Wenn die verstrichene Zeit den Schwellenwert überschreitet, werden Pixel für das nächste Stapel angezeigt. // Berechnen Sie den Indexbereich der Pixel, die zum aktuellen Batch const startIndex = batchIndexref.Current * pixelSize gehören; const endindex = math.min (startindex + pixelSize, pixels.length); // Zeigen Sie die entsprechende Pixelskala auf 1 für (lass i = startIndex; i <endindex; i ++) {newscales [i] = 1; } // Setzen Sie die aktualisierten Maßstabs -Status -Setscales (Newscales); // Fahren Sie mit dem nächsten BatchIndexRef.Current += 1 fort; }}); // Jede Pixelbox -Komponente wird in einer Gruppe platziert, die von GroupRef verwaltet wird, um die Rückkehr zu rendern (<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={scales[i]} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - ordnen<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Render pixelgrid nur, wenn Pixeldaten vorhanden sind */} {Pixels && ( <PixelGrid pixelSize={pixelSize} pixels={pixels} animation={animation} fileChangeCount={fileChangeCount} /> )}</Canvas></div></div> ); }; Standard -Standard -App exportieren; // ===== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo konvertieren // ===== const createpixeldata = (img: htmlimageElement, targetWidth: number, tarnethight: nummer: pixelinfo [] {{{};

Jetzt können Sie sehen, dass es richtig funktioniert, auch wenn Sie das Bild neu laden.

PixelSize wird ebenfalls überwacht. Selbst wenn Sie die Pixelgröße aktualisieren, wird sie erneut angezeigt.

💡Added Explosion Animation !!

Fügen Sie als nächstes eine Explosionsanimation hinzu.
Was wir tun, ist ziemlich einfach: Berechnen Sie zuerst zufällige Koordinaten und verwenden Sie dann UseFrame, um sie in diese Position zu verschieben. Wenn Sie sich wieder normalisieren, können Sie das Gegenteil tun.

// React und drei.JS-bezogene Bibliotheken importieren {OrbitControls} aus "@react-three/drei"; importieren {canvas, useFrame} aus "@react-three/faser"; importieren {usustate, useEffect, useref} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Position jedes Pixels (x, y, z) und Farbe (drei.Color) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Animation_Time: Zeit (in Sekunden) zur Animation // ==== // Pixelgrid -Komponente: // - Renders Gruppen von Pixeldaten und steuert die Anzeige von Animation (allmähliche Vergrößerung) und bewegte Animation (Explosion/Wave) // === Typ PixelGridProps = {{Pixelsize: Nummer; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({pixelsize, pixel, Animation, filechangeCount,}: pixelgridProps) => {// Ein Verweis auf das Gruppenobjekt in drei.js. Wird verwendet, um alle Pixel const GroupRef = Useref zu gruppieren<THREE.Group> (NULL); //- // Animationsfortschritt verwalten (0 bis 1) Const AnimationProgressRef = Useref (0); // für jedes Pixel (für Explosionseffekte) zufällige Streuzielkoordinaten erzeugen (für Explosionseffekte) const scatterPositionSref = useref (pixel.map (() => ({x: (math.random () - 0,5) * 100, y: (math.random () - 0.5) * 100, Z: (Math.Random () - 0.5) * 100,}))). // Zufallsstreukoordinaten regenerieren, wenn Bild- oder Pixeldaten aktualisiert werden. [Pixel]); // Aktualisieren Sie die Position jedes Pixels jeden Frame mit UseFrame, um den Animations -Fortschritt zu übereinstimmen. == "Standard") return; SmoothProgress = Math.Sin ((AnimationProgressRef.Current * Math.pi) / 2); Originalposition zur zufälligen Streuposition (Animation === "Explosion_Start") {targetX = StreuungSref.Current [i] .x * glattprogress + Pixel STRATESREFORSREF.CURRENT [I] .Z * SmoothProgress + Pixel.z * (1 - glattesProgress); STRATIONSPOSIONSREF. Targety, TargetZ); // platziere jede Pixelbox -Komponente in einer Gruppe, die von GroupRef verwaltet wurde, um die Rückkehr zu rendern (<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={scales[i]} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - ordnen<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Render pixelgrid nur, wenn Pixeldaten vorhanden sind */} {Pixels && ( <PixelGrid pixelSize={pixelSize} pixels={pixels} animation={animation} fileChangeCount={fileChangeCount} /> )}</Canvas></div></div> ); }; Standard -Standard -App exportieren; // ===== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo konvertieren // ===== const createpixeldata = (img: htmlimageElement, targetWidth: number, tarnethight: nummer: pixelinfo [] {{{};

Obwohl es einfach ist, denke ich, dass es ein Gefühl zu haben scheint, sich von Pixel aufzuteilen !!

💡 Wellenanimation hinzugefügt !!

Fügen wir auch Wellenanimationen hinzu.
Ich denke, ich kann dies im Grunde genommen auf die gleiche Weise wie eine Explosionsanimation hinzufügen.

// React und drei.JS-bezogene Bibliotheken importieren {OrbitControls} aus "@react-three/drei"; importieren {canvas, useFrame} aus "@react-three/faser"; importieren {usustate, useEffect, useref} aus "react"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Position jedes Pixels (x, y, z) und Farbe (drei.Color) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Animation_Time: Zeit (in Sekunden) zur Animation // ==== // Pixelgrid -Komponente: // - Renders Gruppen von Pixeldaten und steuert die Anzeige von Animation (allmähliche Vergrößerung) und bewegte Animation (Explosion/Wave) // === Typ PixelGridProps = {{Pixelsize: Nummer; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({pixelsize, pixel, Animation, filechangeCount,}: pixelgridProps) => {// Ein Verweis auf das Gruppenobjekt in drei.js. Wird verwendet, um alle Pixel const GroupRef = Useref zu gruppieren<THREE.Group> (NULL); //- // Animationsfortschritt verwalten (0 bis 1) Const AnimationProgressRef = Useref (0); // für jedes Pixel (für Explosionseffekte) zufällige Streuzielkoordinaten erzeugen (für Explosionseffekte) const scatterPositionSref = useref (pixel.map (() => ({x: (math.random () - 0,5) * 100, y: (math.random () - 0.5) * 100, Z: (Math.Random () - 0.5) * 100,}))). // Zufallsstreukoordinaten regenerieren, wenn Bild- oder Pixeldaten aktualisiert werden. [Pixel]); // Aktualisieren Sie die Position jedes Pixels jeden Frame mit UseFrame, um den Animations -Fortschritt zu übereinstimmen. == "Standard") return; SmoothProgress = Math.Sin ((AnimationProgressRef.Current * Math.pi) / 2); Originalposition zur zufälligen Streuposition (Animation === "Explosion_Start") {targetX = StreuungSref.Current [i] .x * glattprogress + Pixel STRATESREFORSREF.CURRENT [I] .Z * SmoothProgress + Pixel.z * (1 - glattesProgress); STRATIONSREFORSREF. "wave_start") {targetZ = math.sin ((pixel.x + pixel.z + AnimationProgressRef.Current * 10) * 0,3) * 5 * glattprogramm;} // Ende der Welle: nach und nach den Welleneffekt und return es zu seinem ursprünglichen Zustand. AnimationProgressRef.Current) * 10) * 0,3) * 5 * (1 - glattesProgramm); // platziere jede Pixelbox -Komponente in einer Gruppe, die von GroupRef verwaltet wurde, um die Rückkehr zu rendern (<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={scales[i]} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - ordnen<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Render pixelgrid nur, wenn Pixeldaten vorhanden sind */} {Pixels && ( <PixelGrid pixelSize={pixelSize} pixels={pixels} animation={animation} fileChangeCount={fileChangeCount} /> )}</Canvas></div></div> ); }; Standard -Standard -App exportieren; // ===== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo konvertieren // ===== const createpixeldata = (img: htmlimageElement, targetWidth: number, tarnethight: nummer: pixelinfo [] {{{};

Ich denke, das kann das Welligkeitsgefühl ausdrücken.

💡Adged Hintergrund !!

Das braucht es nicht, aber ich war ein wenig einsam, also werde ich auch einen Hintergrund hinzufügen.
React Three Drei hat Stern und Wolke, also werde ich sie auf schöne Weise kombinieren.

// React und drei.JS-bezogene Bibliotheken importieren reag, {usestate, useref, memo, useeffect} aus "react"; importieren {canvas, useFrame} aus "@react-three/faser"; Import {Cloud, OrbitControls, Sterne} aus "@react-three/drei"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Verwalten Sie die Position jedes Pixels (x, y, z) und Farbe (drei.Color) // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Default_pixel_size = 64; const Animation_time = 3; // ==== // Pixelgrid -Komponente: // - Rendern Gruppen von Pixeldaten und // - Steuerelemente Die Anzeigeanimation (allmähliche Vergrößerung) und bewegliche Animation (Explosion/Welle) // ==== Typ PixelgridProps = {PixelSize: Nummer; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({PixelSize, Pixel, Animation, FileChoneCount,}: pixelgridProps) => {... // / platzieren Sie jede Pixelbox -Komponente in einer Gruppe, die von GroupRef verwaltet wurde, um die Rückgabe (Return (Return (Return) zu rendern (Return (Return) ()<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={scales[i]} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrales UI -Management (Bildlade-, Pixel -Größen-, Animationsvorgänge) // - ordnen<div style={{ width: "100vw", height: "100vh" }}> {/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- <div className="absolute top-0 left-0 w-full h-full z-[-1]"><Canvas camera={{ position: [0, 5, 15], fov: 50 }} style={{ background: "black" }} ><ambientLight intensity={0.5} /><pointLight position={[10, 10, 10]} intensity={0.5} color="white" /><BackgroundScene /></Canvas></div></div> ); }; // ==== // createPixelData function: // - Get pixel data from the specified image using Canvas and convert it to an array of type PixelInfo // ===== const createPixelData = ( img: HTMLImageElement, targetWidth: number, targetHeight: number ): PixelInfo[] => { ... return result; }; // ===== // Hintergrundszenenkomponente: // - Eine Komponente zum Anzeigen von Sternenhimmel und Wolken im Hintergrund // - Wickeln mit Memo, um unnötiges Neuzug zu verhindern // ===== konstantes backgroppscene = memo (() => {return (<> {/ * repräsentiert den Sternenhimmel mit Sternenkomponenten */} <Stars radius={100} // 星が存在する空間の半径 depth={50} // 星の配置される深さの範囲 count={5000} // 表示する星の総数 factor={6} // 星の大きさ調整用の係数 saturation={1} // 色の鮮やかさ fade // 遠くの星がフェードアウトする効果 /> {/ * Expresswolken mit Wolkenkomponenten */} ausdrücken <Cloud position={[0, 0, 0]} // 雲の中心位置 opacity={0.1} // 雲の不透明度(低いほど透明) speed={0.2} // 雲の動く速度 scale={[10, 10, 10]} // 雲全体のサイズ segments={20} // 雲を構成するパーティクルの数 /></> ); }); Standard -Standard -App exportieren;

Es mag schwer aus dem Video zu erkennen sein, aber es fühlt sich an, als würde der Rauch steigen und es fühlt sich gut an.

💡Final Quellcode !!

💾 GitHub Repository : Überprüfen Sie den Quellcode unter diesem Link

// React und drei.JS-bezogene Bibliotheken importieren reag, {usestate, useref, memo, useeffect} aus "react"; importieren {canvas, useFrame} aus "@react-three/faser"; Import {Cloud, OrbitControls, Sterne} aus "@react-three/drei"; Import * als drei von "drei"; // ------ // Pixelinfo Typ: Verwalten Sie die Position jedes Pixels (x, y, z) und Farbe (drei.Color) // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Default_pixel_size = 64; const Animation_time = 3; // ==== // Pixelgrid -Komponente: // - Rendern Gruppen von Pixeldaten und // - Steuerelemente Die Anzeigeanimation (allmähliche Vergrößerung) und bewegliche Animation (Explosion/Welle) // ==== Typ PixelgridProps = {PixelSize: Nummer; Pixel: Pixelinfo []; Animation: String; filechangeCount: Nummer; }; const pixelgrid = ({pixelsize, pixel, Animation, filechangeCount,}: pixelgridProps) => {// Ein Verweis auf das Gruppenobjekt in drei.js. Wird verwendet, um alle Pixel const GroupRef = Useref zu gruppieren<THREE.Group> (NULL); //-<number[]> (Array (pixels.length) .Fill (0)); // scaleProgressRef: Halten Sie den Anzeigefortschritt (akkumulierte Zeit) für jede Batch const ScaleProgressRef = Useref (0); // batchIndexref: verwaltet die aktuell angezeigte Stapelnummer const batchIndexref = useref (0); // eine Referenz, um festzustellen, ob eine Bilddatei geändert wurde. Const PrevFilechangeCountref = Useref (filechangeCount); // setzt den Anzeigezustand (Skala) aller Pixel beim Nachladen eines BildsEffect (() => {if (fileChoneCount! scaleProgressRef.Current = 0; // Verwenden Sie den Namen, um jeden Frame zu aktualisieren und Pixel Schritt für Schritt verwenden. // Zeit hinzufügen, da der vorherige Frame ScaleProgressRef.Current += Delta; // Berechnen Sie den Zeitschwellenwert, um den aktuellen Batch const Threshold = batchIndexref.current * (Animation_time / (pixels.length / pixelSize)) anzuzeigen; // Wenn die verstrichene Zeit den Schwellenwert überschreitet, werden Pixel für das nächste Stapel angezeigt. // Berechnen Sie den Indexbereich der Pixel, die zum aktuellen Batch const startIndex = batchIndexref.Current * pixelSize gehören; const endindex = math.min (startindex + pixelSize, pixels.length); // Zeigen Sie die entsprechende Pixelskala auf 1 für (lass i = startIndex; i <endindex; i ++) {newscales [i] = 1; } // Setzen Sie die aktualisierten Maßstabs -Status -Setscales (Newscales); // Fahren Sie mit dem nächsten BatchIndexRef.Current += 1 fort; }}); //- // Animationsfortschritt verwalten (0-1) Const AnimationProgressRef = Useref (0); // für jedes Pixel (für Explosionseffekte) zufällige Streukoordinaten (für Explosionseffekte) const scatterPositionSref = useref (pixel.MAP (() => ({x: (math.random () - 0,5) * 100, y: (Math.Random () - 0,5) * 100, Z: (Math.Random () - 0,5) - 0 100,})) generieren. // Regeneration zufälliger Streukoordinaten Wenn Bild- oder Pixeldaten aktualisiert werden. [Pixel]); // Aktualisieren Sie die Position jedes Pixels jeden Frame mit UseFrame, um den Animations -Fortschritt zu übereinstimmen. == "Standard") return; SmoothProgress = Math.Sin ((AnimationProgressRef.Current * Math.pi) / 2); Originalposition zur zufälligen Streuposition (Animation === "Explosion_Start") {targetX = StreuungSref.Current [i] .x * glattprogress + Pixel STRATIONSREFSREF. STRATIONSREFORSREF. "wave_start") {targetZ = math.sin ((pixel.x + pixel.z + AnimationProgressRef.Current * 10) * 0,3) * 5 * glattprogramm;} // Ende der Welle: nach und nach den Welleneffekt und return es zu seinem ursprünglichen Zustand. AnimationProgressRef.Current) * 10) * 0,3) * 5 * (1 - glattesProgramm); // platziere jede Pixelbox -Komponente in einer Gruppe, die von GroupRef verwaltet wurde, um die Rückkehr zu rendern (<group ref={groupRef}> {pixels.map ((Pixel, i) => (<PixelBox key={i} pixel={pixel} scale={scales[i]} /> ))}</group> ); }; // ===== // Pixelbox -Komponente: // - Eine Komponente zum Zeichnen eines einzelnen Pixel (Box) // ==== Typ PixelBoxProps = {Pixel: Pixelinfo; Skala: Zahl; }; const pixelbox = ({Pixel, Skalierung}: pixelBoxProps) => {// Mesh: Verwenden Sie die Box -Geometrie und das Material mit Standort und Skalierungsrendite (Return (Return () <mesh position={[pixel.x, pixel.y, pixel.z]} scale={[scale, scale, scale]}><boxGeometry args={[1, 1, 1]} /><meshStandardMaterial color={pixel.color} /></mesh> ); }; // ===== // App -Komponente: // - Zentrale UI -Verwaltung (Bildlade, Pixelgrößen, Animationsvorgänge) // - Anordnen zwei Leinwand (Pixel -Szene und Hintergrundszene) // ===== const App = () => {// State Management: // Pixel: Array: Array von Pixel -Pixel -Pixel. Tatsächliche Pixelgröße angewendet // - filechangeCount: Anzahl der Änderungen am Bild (zum Auslösen eines Reloads verwendet) // - ImagesRC: Daten -URL des importierten Bildes // - Animation: Aktueller Animationsmodus const [Pixel, SetPixel] = Usestate<PixelInfo[] | null> (NULL); const [temppixelSize, settemppixelSize] = Usestate<number> (Default_pixel_size); const [pixelSize, setpixelSize] = Usestate<number> (temppixelSize); const [filechangeCount, setFilechangeCount] = Usestate<number> (0); const [ImagesRC, setImagesrc] = Usestate<string | null> (NULL); const [Animation, setAnimation] = usustate ("Standard"); // ------ // Was ist zu tun, wenn eine Bilddatei ausgewählt wird: //-Die Datei laden, in eine Daten-URL konvertieren und in ImagesRC // festlegen ---------------------------------------------------------------------------------------------------------------------------------------------------------<HTMLInputElement> ) => {const File = e.target.files?. [0]; if (! file) return; const reader = new fileReader (); reader.onload = (ev) => {const url = ev.target?.result; if (typeof url! == "String") zurück; // Die Pixelgröße einmal aktualisieren und dann die Bildquelle setpixelSize (temppixelSize) festlegen. setImagesRC (URL); }; Reader.ReadasDataurl (Datei); }; // ------ // Verarbeitung beim Drücken der Schaltfläche "Überprüfung": //-das Bild neu zeichnen, indem Sie den Wert von temppixelSize in PixelSize reflektieren // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ }, [pixelSize, ImagesRC]); // ------ // Explosionsanimation steuern: //-Start, beenden und rückgängig machen die Explosion führt nacheinander Timeout // aus // --------------------------------------------------------------------------------------------------------------------------------------------------------- setAnimation ("explosion_end"); }, Animation_time * 1000); setTimeout (() => {console.log ("default"); setAnimation ("default");}, Animation_Time * 2000); }; // ------ // Wave Animation Control: //-Starten, Ende und Rückgängigungen nacheinander Timeout // führen ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div style={{ width: "100vw", height: "100vh" }}> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div className="absolute top-4 left-4 bg-white shadow-lg p-4 rounded-lg z-10 w-64 space-y-4"> {/ * Bilddatei */} auswählen <input type="file" accept="image/*" onChange={handleFileChange} className="w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" /> {/ * Pixelgrößeneingangsfeld */}<div className="flex items-center space-x-2"> <label className="text-sm text-gray-700">Pixelgröße:</label><input type="number" value={tempPixelSize} onChange={(e) => settemppixelSize (number (e.target.Value))} min = "1" max = "128" classname = "w-16 Border Border-Gray-300 Rounded-2 Py-1 Text-SM Fokus: Ring-2 Fokus: Ring-Blue-500 Fokus: SUCKLINE-NONE" /></div> {/ * Redisplay -Schaltfläche */} <button className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition" onClick={reloadImage} >Redisplay</button> {/ * Animation Control Button */}<div className="flex flex-wrap gap-2"> <button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition" onClick={controlExplosionAnimation} >Explosionswelle</button> <button className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition" onClick={controlWaveAnimation} >​</button></div></div> {/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ <div className="absolute top-0 left-0 w-full h-full z-[1]"><Canvas camera={{ far: 5000, position: [0, 0, 100] }}> {/ * Basisbeleuchtungseinstellungen */}<ambientLight intensity={1} /><directionalLight position={[100, 200, 100]} intensity={1} /> {/ * OrbitControls, mit denen Sie die Szene mit Mausoperation drehen können */}<OrbitControls /> {/ * Render pixelgrid nur, wenn Pixeldaten vorhanden sind */} {Pixels && ( <PixelGrid pixelSize={pixelSize} pixels={pixels} animation={animation} fileChangeCount={fileChangeCount} /> )}</Canvas></div> {/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- <div className="absolute top-0 left-0 w-full h-full z-[-1]"><Canvas camera={{ position: [0, 5, 15], fov: 50 }} style={{ background: "black" }} ><ambientLight intensity={0.5} /><pointLight position={[10, 10, 10]} intensity={0.5} color="white" /><BackgroundScene /></Canvas></div></div> ); }; // ==== // createpixeldata Funktion: // - Pixeldaten aus dem angegebenen Bild mit Leinwand abrufen und in ein Array von Typ Pixelinfo umwandeln die angegebene Größe const canvas = document.createelement ("canvas"); canvas.width = targetwidth; Canvas.Height = Taretheight; const ctx = canvas.getContext ("2d"); if (! ctx) werfen einen neuen Fehler ("Nr. 2D -Kontext verfügbar"); // das Bild auf Leinwand zeichne und Pixelinformationen ctx.drawimage (IMG, 0, 0, Targetwidth, Taretheight) erhalten; const imgdata = ctx.getImagedata (0, 0, targetwidth, targeeteight); const data = imgdata.data; const Ergebnis: pixelinfo [] = []; lass idx = 0; // für jedes Pixel im Bild den RGBA -Wert abrufen und in Pixelinfo für (sei y = 0; y <taretheight; y ++) {für (let x = 0; x <targetWidth; x ++) {const r = data [idx], g = daten [idx+1], b = data [idx+2], a = Data [idx+3]; IDX += 4; // Pixel mit niedriger Transparenz (a <30) ignorieren, wenn (a <30) fortgesetzt wird; result.push ({// x, y -Koordinaten so, dass die Bildmitte der Ursprung x: x - Zielbreite / 2, y: -y + taretheight / 2, z: 0, // Erstellen Sie drei. }} Rückgabeergebnis; }; // ====== // Hintergrundszenenkomponente: // - Eine Komponente zum Anzeigen von Sternenhimmel und Wolken im Hintergrund // - Eine Verpackung mit Memo, um unnötiges Neuzufall zu verhindern // ===== konstantes konstantes backgroppscene = memo (() => {return (<> {/ * Repräsentation von Sternenhimmel mit Sternenkomponenten */} <Stars radius={100} // 星が存在する空間の半径 depth={50} // 星の配置される深さの範囲 count={5000} // 表示する星の総数 factor={6} // 星の大きさ調整用の係数 saturation={1} // 色の鮮やかさ fade // 遠くの星がフェードアウトする効果 /> {/ * Expresswolken mit Wolkenkomponenten */} ausdrücken <Cloud position={[0, 0, 0]} // 雲の中心位置 opacity={0.1} // 雲の不透明度(低いほど透明) speed={0.2} // 雲の動く速度 scale={[10, 10, 10]} // 雲全体のサイズ segments={20} // 雲を構成するパーティクルの数 /></> ); }); Standard -Standard -App exportieren;

schließlich

Dieses Mal haben wir drei Faser reagiert, um Pixelkunst und dynamische Animationen aus Bildern zu erstellen, und reagieren drei Faser und reagieren drei Drei auf animierte Pixelkunst und Pixelkunst !!

Ich denke, Sie können etwas noch cooleres erstellen, wenn Sie die Anzahl der Implementierungen frei erhöhen. Probieren Sie es also aus!

Sie können ein detailliertes Verständnis der tatsächlichen Bewegungen erhalten, indem Sie die YouTube unten ansehen!

📺 Sehen Sie sich die Demo auf YouTube an : Sie können sie aus diesem Link

📌Der Code, den ich dieses Mal erstellt habe, ist auf GitHub veröffentlicht. Bitte schauen Sie sich auch an!

💾 GitHub Repository : Überprüfen Sie den Quellcode unter diesem Link

📌 Wenn Sie Mesh verwenden und es durch ein 3D -Objekt ersetzen, können Sie sich Ihrem Ideal sogar näher kommen !!

Meshy ist ein Dienst, mit dem Sie mit AI problemlos 3D -Objekte generieren können.
Wenn Sie dies verwenden, können Sie Ihr ideales 3D -Objekt problemlos erstellen, damit Sie Ihrem Ideal noch näher kommen können!

📺 Mesh überprüfen : Sie können es auf der offiziellen Seite von diesem Link

Wenn Sie dies hilfreich fanden, abonnieren Sie bitte unseren Kanal!

Wir werden in Zukunft weiterhin Lektionen und Arbeiten von TypeScript X reagieren.
Wir werden eine Ankündigung auf YouTube machen. Abonnieren Sie also unseren YouTube -Kanal und warten Sie auf Benachrichtigungen!

📺 YouTube ansehen : Sie können es von diesem Link

Wenn Sie wissen möchten, was Reagieren von drei Fasern tun können, beziehen Sie sich bitte Folgendes!
Wir haben benutzerfreundliche Arbeiten zur Verfügung!

Teilen Sie, wenn Sie möchten!

Wer hat diesen Artikel geschrieben

Dies ist ein Blog, in dem ich angefangen habe, Informationssicherheit zu studieren. Als neuer Angestellter würde ich mich freuen, wenn Sie mit einem breiten Herzen schauen könnten.
Es gibt auch Teech Lab, das eine Gelegenheit ist, Programmierspaß zu studieren. Wenn Sie also an der Softwareentwicklung interessiert sind, sollten Sie sich unbedingt ansehen!

Inhaltsverzeichnis