Let’s take a look at the panoramic view effect: Display address After experiencing it, do you feel that the surrounding environment has rotated in a circle and that the world is round? 😁 Panoramic effect realizationWith the above tips, friends who have a little knowledge of threejs may have guessed that this panoramic effect is actually achieved using a sphere~ and we just pasted a texture map on the inner surface of the sphere (you can see this sphere by rolling the wheel outwards. It looks like a glass ball, which is very beautiful. There is also an easter egg 😁 (well, it’s not an easter egg if you say it out)): Initially, our perspective is at the center of the sphere, and the movement of the perspective is controlled by the Then the code to create this sphere is as follows: const geometry = new THREE.SphereBufferGeometry(500, 32, 32); geometry.scale(-1, 1, 1); // Reverse the texture const material = new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(imglist[0].default) // Pass in the URL or path of the image, or a Data URI. }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); const controls = new OrbitControls(camera, renderer.domElement); controls.enablePan = false; controls.maxDistance = 1000;
Carousel The carousel is implemented using the swiper library, which is very convenient to use. You can refer to the documentation for details. onSliderChange = curSwiper => { const mesh = this.mesh; const texture = imglist[curSwiper.activeIndex].default; mesh.material.map = new THREE.TextureLoader().load(texture); }; Below is my swiper settings, where SwiperSlider is a slidable carousel card, EffectCoverflow is the effect triggered when sliding, and swiper provides four optional effects: Fade, Coverflow, Flip and Cube. import { Swiper, SwiperSlide } from 'swiper/react'; import SwiperCore, { EffectCoverflow } from 'swiper'; import 'swiper/swiper.min.css'; import 'swiper/components/effect-coverflow/effect-coverflow.min.css'; SwiperCore.use([EffectCoverflow]); //.... <Swiper className='panoramic-imgs' spaceBetween={50} // Spacing slidesPerView={3} // Number of images that can be previewed in the slideshow onSlideChange={this.onSliderChange} // Callback triggered when sliding onSwiper={(swiper) => console.log(swiper)} // Callback triggered on initial load direction='vertical' // Slideshow direction, horizontal by default effect={'coverflow'} // Slide effect grabCursor={true} // Whether to display drag when the mouse is placed on the carousel centeredSlides={true} // Whether the currently active image should be centered coverflowEffect={{ // Coverflow effect parameter settings, you can adjust it yourself "rotate": 50, "stretch": 0, "depth": 100, "modifier": 1, "slideShadows": true }} { imglist.map((img, idx) => { return <SwiperSlide key={idx}> <img src={img.default} className='panoramic-img'></img> </SwiperSlide> }) } </Swiper> That's all about the implementation of the panoramic effect. Of course, if you have any questions, you can leave a message or refer to my code (posted below). As long as you have a certain understanding of threejs and react, I believe it is not difficult to achieve such an effect, and the amount of code is also very small~ Complete code import React, { Component } from 'react'; import Layout from '@theme/Layout'; import Head from '@docusaurus/Head'; import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import * as _ from 'underscore'; import { message } from 'antd'; import { Swiper, SwiperSlide } from 'swiper/react'; import SwiperCore, { EffectCoverflow } from 'swiper'; import 'swiper/swiper.min.css'; import 'swiper/components/effect-coverflow/effect-coverflow.min.css'; import './index.css'; import imgs from './imgs.json'; SwiperCore.use([EffectCoverflow]); const imglist = imgs.map(img => { return require('../../../static/img/panoramic/' + img.name); }); export default class Panormatic extends Component { constructor() { super(); this.renderer = null; this.camera = null; this.scene = null; this.container = null; this.controls = null; this.showMessage = true; // Easter egg prompt} componentDidMount() { const container = document.getElementById('panoramic-canvas-container'); const canvas = document.getElementById('panoramic-canvas'); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true }); renderer.setClearColor(0xffffff); // b2e0df mung bean paste colorrenderer.setPixelRatio( window.devicePixelRatio ); const height = container.clientHeight; const width = container.clientWidth; renderer.setSize(width, height); const camera = new THREE.PerspectiveCamera(60, width / height, 1, 30000); camera.position.set(0, 0, 1); camera.center = new THREE.Vector3(0, 0, 0); const scene = new THREE.Scene(); const geometry = new THREE.SphereBufferGeometry(500, 32, 32); geometry.scale(-1, 1, 1); // Reverse the texture const material = new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(imglist[0].default) }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); const controls = new OrbitControls(camera, renderer.domElement); // controls.enableZoom = false; controls.enablePan = false; controls.maxDistance = 1000; this.renderer = renderer; this.camera = camera; this.scene = scene; this.container = container; this.controls = controls; this.mesh = mesh; // Set the global configuration of the prompt box message.config({ top: 100, duration: 3.5, maxCount: 1, }); this.onControlsChange = _.throttle(this.onChange, 100); controls.addEventListener('change', this.onControlsChange); window.addEventListener('resize', this.onWindowResize); this.renderLoop(); } componentWillUnmount() { const mesh = this.mesh; mesh.material.dispose(); mesh.geometry.dispose(); this.scene.remove(mesh); window.removeEventListener('resize', this.onWindowResize); this.controls.removeEventListener('change', this.onControlsChange); message.destroy(); } onChange = (e) => { const camera = this.camera; if (camera.position.distanceTo(camera.center) >= 700) { if (this.showMessage) { message.success('🎊Congratulations on discovering the little secret of panoramic effect~🎉'); this.showMessage = false; } } else { this.showMessage = true; } } onSliderChange = (curSwiper) => { const mesh = this.mesh; const texture = imglist[curSwiper.activeIndex].default; mesh.material.map = new THREE.TextureLoader().load(texture); }; onWindowResize = () => { const camera = this.camera; const renderer = this.renderer; const width = this.container.clientWidth; const height = this.container.clientHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); }; renderLoop = () => { this.renderer.render(this.scene, this.camera); requestAnimationFrame(this.renderLoop); }; render() { return ( <Layout> <Head> <title>Panorama | Yle</title> </Head> <div id='panoramic-container'> <Swiper className='panoramic-imgs' spaceBetween={50} slidesPerView={3} onSlideChange={this.onSliderChange} onSwiper={(swiper) => console.log(swiper)} direction='vertical' effect={'coverflow'} grabCursor={true} centeredSlides={true} coverflowEffect={{ "rotate": 50, "stretch": 0, "depth": 100, "modifier": 1, "slideShadows": true }} > { imglist.map((img, idx) => { return <SwiperSlide key={idx}> <img src={img.default} className='panoramic-img'></img> </SwiperSlide> }) } </Swiper> <div id='panoramic-canvas-container'> <canvas id='panoramic-canvas'></canvas> </div> </div> </Layout> ); } } This is the end of this article about the complete code of React + Threejs + Swiper to achieve panoramic effect. For more relevant React panorama content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: How to solve the problem that VMware virtual machine bridge mode cannot access the Internet
Virtual machines are very convenient testing soft...
While working on a Linux server, assigning static...
Install and configure the MySql database system. ...
Defining an array in Bash There are two ways to c...
Introduction to common Dockerfile instructions in...
When making forms, we often encounter the situati...
The previous article wrote about how to manually ...
If you want to install multiple tomcats, you must...
Table of contents question Server layer and stora...
Method 1: Use the SET PASSWORD command MySQL -u r...
This article example shares the specific code of ...
Table of contents Overview 1. Develop the require...
Table of contents principle Network environment p...
This article example shares the specific code for...
Table of contents Preface 1. Null coalescing oper...