React + Threejs + Swiper vollständiger Code zum Erzielen eines Panoramaeffekts

React + Threejs + Swiper vollständiger Code zum Erzielen eines Panoramaeffekts

Schauen wir uns den Panorama-Effekt an: Adresse anzeigen
Screenshot:

Panorama

Haben Sie nach dem Erleben das Gefühl, dass sich die umgebende Umwelt kreisförmig dreht und die Welt rund ist? 😁
Das stimmt! Herzlichen Glückwunsch, dass Sie es richtig gemacht haben! Die Erde ist rund! 👀

Realisierung von Panoramaeffekten

Freunde, die sich ein wenig mit Threejs auskennen, haben anhand der obigen Tipps vielleicht schon erraten, dass dieser Panoramaeffekt tatsächlich mithilfe einer Kugel erreicht wird~ und wir haben einfach eine Texturkarte auf die Innenfläche der Kugel geklebt (Sie können diese Kugel sehen, indem Sie das Rad nach außen rollen. Sie sieht aus wie eine Glaskugel, was sehr schön ist. Außerdem gibt es ein Easter Egg 😁 (also, wenn man es ausspricht, ist es kein Easter Egg)):

Bildbeschreibung hier einfügen

Zunächst befindet sich unsere Perspektive im Zentrum der Kugel und die Bewegung der Perspektive wird durch das von threejs bereitgestellte Tool OrbitControls gesteuert.

Der Code zum Erstellen dieser Kugel lautet dann wie folgt:

const Geometrie = neue THREE.SphereBufferGeometry(500, 32, 32);
geometry.scale(-1, 1, 1); // Textur umkehren const material = new THREE.MeshBasicMaterial({
    Map: new THREE.TextureLoader().load(imglist[0].default) // Geben Sie die URL oder den Pfad des Bildes oder eine Daten-URI ein.
});
const mesh = neues THREE.Mesh(Geometrie, Material);
Szene.Hinzufügen(Netz);

const-Steuerungen = neue OrbitControls (Kamera, Renderer.domElement);
steuert.enablePan = false;
steuert.maxDistance = 1000;

Wenn Sie nicht wissen, was Data URI ist, können Sie die MDN-Dokumentation lesen.

Karussell

Das Karussell wird mithilfe der Swiper-Bibliothek implementiert, die sehr bequem zu verwenden ist. Weitere Einzelheiten finden Sie in der Dokumentation.
Beim Verschieben des Karussells wird ein onSliderChange -Ereignis ausgelöst. Dieses Ereignis übergibt den aktuellen swiper als Parameter. Wir können das Bild über das aktuell aktivierte Element abrufen und die Texturkarte der Kugel ersetzen:

beiSliderChange = curSwiper => {
    const mesh = dieses.mesh;
    const texture = imglist[curSwiper.activeIndex].default;
    mesh.material.map = neues THREE.TextureLoader().load(texture);
};

Unten sind meine Swiper-Einstellungen, wobei SwiperSlider eine verschiebbare Karussellkarte ist, EffectCoverflow der beim Schieben ausgelöste Effekt ist und Swiper vier optionale Effekte bietet: Fade, Coverflow, Flip und Cube. imglist ist eine Gruppe von Bildern, wobei imglist[i].default die Base64-Kodierung des Bildes speichert.

importiere { Swiper, SwiperSlide } von „swiper/react“;
importiere SwiperCore, { EffectCoverflow } von „swiper“;
importiere „swiper/swiper.min.css“;
importiere „swiper/Komponenten/Effekt-Coverflow/Effekt-Coverflow.min.css“;

SwiperCore.use([EffectCoverflow]);

//....
<Swiper
    Klassenname = "Panoramabilder"
    spaceBetween={50} // Abstand slidesPerView={3} // Anzahl der Bilder, die in der Diashow in der Vorschau angezeigt werden können onSlideChange={this.onSliderChange} // Rückruf wird beim Verschieben ausgelöst onSwiper={(swiper) => console.log(swiper)} // Rückruf wird beim ersten Laden ausgelöst direction='vertical' // Diashow-Richtung, standardmäßig horizontal
    effect={'coverflow'} // Folieneffekt grabCursor={true} // Ob Drag angezeigt werden soll, wenn die Maus über das Karussell bewegt wird centeredSlides={true} // Ob das aktuell aktive Bild zentriert werden soll coverflowEffect={{ // Einstellungen der Coverflow-Effektparameter, Sie können sie selbst anpassen "rotate": 50,
        "strecken": 0,
        "Tiefe": 100,
        "Modifikator": 1,
        "slideShadows": wahr
    }}
    {
        imglist.map((img, idx) => {
            zurück <SwiperSlide key={idx}>
                <img src={img.default} Klassenname='Panoramabild'></img>
            </SwiperSlide>
        })
    }
</Swiper>

Das ist alles zur Implementierung des Panoramaeffekts. Wenn Sie Fragen haben, können Sie natürlich eine Nachricht hinterlassen oder auf meinen Code (unten veröffentlicht) verweisen. Solange Sie ein gewisses Verständnis von Threejs und React haben, ist es meiner Meinung nach nicht schwierig, einen solchen Effekt zu erzielen, und die Codemenge ist auch sehr gering ~

Vollständiger Code

importiere React, {Komponente} von „react“;

Layout aus „@theme/Layout“ importieren;
Head aus „@docusaurus/Head“ importieren;

importiere * als DREI von „drei“;
importiere { OrbitControls } aus 'three/examples/jsm/controls/OrbitControls';
importiere * als _ von „Unterstrich“;
importiere {Nachricht} von „antd“;

importiere { Swiper, SwiperSlide } von „swiper/react“;
importiere SwiperCore, { EffectCoverflow } von „swiper“;
importiere „swiper/swiper.min.css“;
importiere „swiper/Komponenten/Effekt-Coverflow/Effekt-Coverflow.min.css“;

importiere './index.css';
importiere Bilder aus „./imgs.json“;

SwiperCore.use([EffectCoverflow]);

const imglist = imgs.map(img => {
    Rückgabewert: erfordert('../../../static/img/panoramic/' + img.name);
});

exportiere Standardklasse Panormatic erweitert Komponente {
    Konstruktor() {
        super();
        dieser.renderer = null;
        diese.Kamera = null;
        diese.Szene = null;
        dieser.container = null;
        diese.Steuerungen = null;
        this.showMessage = true; // Easter Egg-Eingabeaufforderung}

    componentDidMount() {
        const container = document.getElementById('Panorama-Canvas-Container');
        const canvas = document.getElementById('panoramic-canvas');
        const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });

        renderer.setClearColor(0xffffff); // b2e0df Mungobohnenpaste Farbrenderer.setPixelRatio( window.devicePixelRatio );
        const Höhe = Container.Clienthöhe;
        const width = container.clientWidth;
        renderer.setSize(Breite, Höhe);
        
        const Kamera = neue THREE.PerspectiveCamera (60, Breite / Höhe, 1, 30000);
        Kamera.Position.einstellen(0, 0, 1);
        Kamera.Mitte = neuer DREI.Vektor3(0, 0, 0);

        const Szene = neue DREI.Szene();

        const Geometrie = neue THREE.SphereBufferGeometry(500, 32, 32);
        geometry.scale(-1, 1, 1); // Textur umkehren const material = new THREE.MeshBasicMaterial({
            Karte: neues THREE.TextureLoader().load(imglist[0].default)
        });
        const mesh = neues THREE.Mesh(Geometrie, Material);
        Szene.Hinzufügen(Netz);

        const-Steuerungen = neue OrbitControls (Kamera, Renderer.domElement);
        // steuert.enableZoom = false;
        steuert.enablePan = false;
        steuert.maxDistance = 1000;

        dieser.renderer = Renderer;
        diese.kamera = Kamera;
        diese.Szene = Szene;
        dieser.container = Container;
        this.controls = Steuerelemente;
        dies.mesh = Mesh;

        // Legen Sie die globale Konfiguration des Eingabeaufforderungsfelds fest message.config({
            oben: 100,
            Dauer: 3,5,
            maxAnzahl: 1,
        });

        this.onControlsChange = _.throttle(this.onChange, 100);
        steuert.addEventListener('ändern', this.onControlsChange);
        window.addEventListener('Größe ändern', this.onWindowResize);
        dies.renderLoop();
    }

    componentWillUnmount() {
        const mesh = dieses.mesh;
        mesh.material.entsorgen();
        mesh.geometry.dispose();
        diese.Szene.entfernen(Netz);
        window.removeEventListener('Größe ändern', this.onWindowResize);
        this.controls.removeEventListener('ändern', this.onControlsChange);
        Nachricht.zerstören();
    }

    beiÄnderung = (e) => {
        const Kamera = diese.Kamera;
        wenn (Kamera.Position.AbstandZu(Kamera.Mitte) >= 700) {
            wenn (diese.showMessage) {
                message.success('🎊Herzlichen Glückwunsch zur Entdeckung des kleinen Geheimnisses des Panoramaeffekts~🎉');
                diese.showMessage = falsch;
            }
        } anders {
            diese.showMessage = wahr;
        }
    }

    beiSliderChange = (aktuellerSwiper) => {
        const mesh = dieses.mesh;
        const texture = imglist[curSwiper.activeIndex].default;
        mesh.material.map = neues THREE.TextureLoader().load(texture);
    };

    beiFenstergröße ändern = () => {
        const Kamera = diese.Kamera;
        const renderer = dieser.renderer;
        const width = this.container.clientWidth;
        const Höhe = dieser.Container.ClientHeight;
        
        Kamera.Aspekt = Breite / Höhe;
        Kamera.updateProjectionMatrix();
        
        renderer.setSize(Breite, Höhe);
    };

    renderLoop = () => {
        dieser.Renderer.render(diese.Szene, diese.Kamera);
        requestAnimationFrame(diese.renderLoop);
    };

    rendern() {
        zurückkehren (
            <Layout>
                <Kopf>
                    <title>Panorama | Yle</title>
                </Kopf>
                <div id='Panorama-Container'>
                    <Swiper
                        Klassenname = "Panoramabilder"
                        AbstandBetween={50}
                        slidesPerView={3}
                        beiSlideChange={this.onSliderChange}
                        onSwiper={(swiper) => console.log(swiper)}
                        Richtung='vertikal'
                        Effekt = {'Coverflow'}
                        grabCursor={true}
                        zentrierte Folien = {true}
                        coverflowEffekt={{
                            "drehen": 50,
                            "strecken": 0,
                            "Tiefe": 100,
                            "Modifikator": 1,
                            "slideShadows": wahr
                        }}
                    >
                        {
                            imglist.map((img, idx) => {
                                zurück <SwiperSlide key={idx}>
                                    <img src={img.default} Klassenname='Panoramabild'></img>
                                </SwiperSlide>
                            })
                        }
                    </Swiper>
                    <div id='Panorama-Leinwand-Container'>
                        <Leinwand-ID = 'Panorama-Leinwand'></Leinwand>
                    </div>
                </div>
                
                
            </Layout>
        );
    }
}

Dies ist das Ende dieses Artikels über den vollständigen Code von React + Threejs + Swiper zum Erzielen eines Panoramaeffekts. Weitere relevante React-Panoramainhalte finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Ein vollständiges Beispiel für die Verwendung von three.js zur Realisierung von Panorama in Vue
  • Realisierung von 360-Grad-Panoramabildern auf Basis von Three.js
  • Erstellen Sie ein 360-Grad-Panorama basierend auf dem Three.js-Plugin
  • THREE.JS Erste Schritte Tutorial (6) Schritte zum Erstellen Ihres eigenen Panoramas
  • JS realisiert 360-Grad-Rotation des Panoramabildeffekts

<<:  So lösen Sie das Problem, dass der Bridge-Modus der virtuellen VMware-Maschine nicht auf das Internet zugreifen kann

>>:  Detaillierte Erklärung des unbekannten Fehlers 10061 bei der Verwendung von Navicat zur Verbindung mit einer Remote-Linux-MySQL-Datenbank

Artikel empfehlen

Detaillierte Schritte zur schnellen Installation von Openshift

Der schnellste Weg, die neueste Version von OpenS...

Vor- und Nachteile von MySQL-Indizes und Richtlinien zum Erstellen von Indizes

1. Warum einen Index erstellen? (Vorteile) Dies l...

Bootstrap+Jquery zum Erreichen eines Kalendereffekts

In diesem Artikel wird der spezifische Code von B...

So ermitteln Sie die Ausführungszeit eines Befehls oder Prozesses in Linux

Auf Unix-ähnlichen Systemen wissen Sie möglicherw...

Details zur Verwendung regulärer Ausdrücke in MySQL

Inhaltsverzeichnis 1. Einleitung 2. Bereiten Sie ...

JS realisiert den Effekt der Baidu News-Navigationsleiste

In diesem Artikel wird der spezifische JS-Code zu...

...

Vue: Zwei Komponenten auf gleicher Ebene erreichen eine Wertübertragung

Vue-Komponenten sind verbunden, daher ist es unve...

Sollten nullbare Felder in MySQL auf NULL oder NOT NULL gesetzt werden?

Personen, die MySQL häufig verwenden, können mit ...

JavaScript-Countdown zum Schließen von Anzeigen

Verwenden von Javascript zum Implementieren eines...