千家信息网

React+Threejs+Swiper如何实现全景图效果

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇"React+Threejs+Swiper如何实现全景图效果"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获
千家信息网最后更新 2026年11月02日React+Threejs+Swiper如何实现全景图效果

这篇"React+Threejs+Swiper如何实现全景图效果"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"React+Threejs+Swiper如何实现全景图效果"文章吧。

全景效果实现

  有了上面的提示,对 threejs 有一点了解的小伙伴可能就猜出来了,这个全景效果其实就是使用一个球体实现的~ 而我们只是在球体内表面上贴了一张纹理贴图而已(滚轮向外滚就可以看到这个球体了,看上去像个玻璃球,怪好看的,还有个彩蛋?(好吧,说出来就不是彩蛋了)):

  初始时,我们的视角在球体正中心,视角的移动则是依靠 threejs 提供的工具 OrbitControls 来控制。

  那么创建这个球体的代码如下:

const geometry = new THREE.SphereBufferGeometry(500, 32, 32);geometry.scale(-1, 1, 1);   // 将纹理反贴const material = new THREE.MeshBasicMaterial({    map: new THREE.TextureLoader().load(imglist[0].default)       // 传入图片的URL或者路径,也可以是 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;

不知道 Data URI 是什么的可以看看 MDN 文档

轮播图

  轮播图实现则是使用 swiper 这个库,使用起来非常方便,具体可自行查阅文档。
  在滑动轮播图时,会触发一个 onSliderChange 事件,这个事件传入当前的 swiper 作为参数,我们就可以通过当前激活的元素来获取图片并替换球体的纹理贴图了:

onSliderChange = curSwiper => {    const mesh = this.mesh;    const texture = imglist[curSwiper.activeIndex].default;    mesh.material.map = new THREE.TextureLoader().load(texture);};

  下面是我的 swiper 设置,其中 SwiperSlider 是一个可滑动的轮播图卡片,EffectCoverflow 是滑动时触发的效果,swiper 中提供了四种可选效果:Fade、Coverflow、Flip 以及 Cube。imglist 则是一组图片,其中 imglist[i].default 属性保存了图片的 base64 编码。

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]);//.... console.log(swiper)} // 初始加载时触发的回调    direction='vertical'    // 轮播图方向,默认是水平 horizontal    effect={'coverflow'}    // 滑动效果    grabCursor={true}       // 鼠标放在轮播图上是否显示拖拽    centeredSlides={true}   // 当前处于激活状态的图片是否要居中    coverflowEffect={{      // coverflow 效果参数设置,可自行调整        "rotate": 50,        "stretch": 0,        "depth": 100,        "modifier": 1,        "slideShadows": true    }}    {        imglist.map((img, idx) => {            return                                     })    }

  全景效果的实现就说到这了,当然,如果什么地方有疑问可以留言或者参考我的代码(下面贴出来),只要对 threejs 和 react 有一定了解的同学我相信实现这么一个效果并不难,代码量也很小~

完整代码

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;    // 彩蛋提示    }    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 绿豆沙色        renderer.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);   // 将纹理反贴        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;        // 设置提示框的全局配置        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('?恭喜你发现了全景效果的小秘密~?');                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 (                                                全景图 | Yle                                
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 }) }
); }}

以上就是关于"React+Threejs+Swiper如何实现全景图效果"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

效果 全景 球体 内容 图片 代码 纹理 彩蛋 提示 事件 参数 就是 文档 文章 激活 知识 篇文章 视角 贴图 好看 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海喔噻互联网科技有限公司 互联网科技公司起名 科技企业和互联网企业 易通互联网络科技有限公司 互联网金融科技委员会 互联网巨头投资的硬核科技 互联网 科技馆 彤创互联网科技有限公司 开一家科技互联网公司需要多少钱 乌鲁木齐新华智原互联网科技学校 佛山市翊博互联网络科技有限公司 上海钢联属于互联网科技股吗 伍佰万互联网科技怎么赚钱 互联网科技融合创新 风投北京互联网科技 信承诺互联网科技有限公司 全球科技与互联网公司市值变化 吉林省码上互联网科技电话 恒生科技互联网指数十大成分股 科技发展第三阶段互联网时代 互联网加科技 喔噻互联网科技有限公司 涨乐互联网科技 互联网科技与金融科技 苏州互联网科技贷款公司 互联网企业和科技型企业 沐思想互联网科技有限公司 福建互联网展示科技馆设计 互联网界的黑科技 现代科技的标志之一的互联网
0