iis服务器助手广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >React + Threejs + Swiper 实现全景图效果的完整代码
  • 211
分享到

React + Threejs + Swiper 实现全景图效果的完整代码

2024-04-02 19:04:59 211人浏览 八月长安
摘要

  咱先看看全景图实现效果:展示地址   截图:   体验了一下是不是感觉周围环境转了一圈,感觉世界是圆的?

  咱先看看全景图实现效果:展示地址
  截图:

全景图

  体验了一下是不是感觉周围环境转了一圈,感觉世界是圆的?😁
  没错!恭喜你答对了!地球就是圆的!👀

全景效果实现

  有了上面的提示,对 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]);

//....
<Swiper
    className='panoramic-imgs'
    spaceBetween={50}	// 间距
    slidesPerView={3}	// 轮播图里可预览图片数
    onSlideChange={this.onSliderChange}	// 滑动时触发的回调
    onSwiper={(swiper) => 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 <SwiperSlide key={idx}>
                <img src={img.default} className='panoramic-img'></img>
            </SwiperSlide>
        })
    }
</Swiper>

  全景效果的实现就说到这了,当然,如果什么地方有疑问可以留言或者参考我的代码(下面贴出来),只要对 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 (
            <Layout>
                <Head>
                    <title>全景图 | 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>
        );
    }
}

到此这篇关于React + Threejs + Swiper 实现全景图效果的完整代码的文章就介绍到这了,更多相关React全景图内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: React + Threejs + Swiper 实现全景图效果的完整代码

本文链接: https://www.lsjlt.com/news/129292.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React + Threejs + Swiper 实现全景图效果的完整代码
      咱先看看全景图实现效果:展示地址   截图:   体验了一下是不是感觉周围环境转了一圈,感觉世界是圆的?...
    99+
    2024-04-02
  • threejs全景图和锚点编辑的实现方案
    目录全景图和锚点编辑全景图全景图拆解场景编辑方案transformControls初始化控制器添加可移动对象平移、缩放、旋转保存对象结语全景图和锚点编辑 今天来简单聊聊threejs...
    99+
    2024-04-02
  • Canvas实现放大镜效果完整案例分析(附代码)
    小编给大家分享一下Canvas实现放大镜效果完整案例分析(附代码),相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一张模糊的图片:鼠标点击任意位置,产生放大效果:哇...
    99+
    2023-06-09
  • Java实现截图小工具的完整代码
    目录写在前面效果展示代码展示项目结构设计思路项目测试写在前面 今天利用Java的图形用户界面GUI技术写了一个电脑截图小工具。本程序代码简单,涉及到异常处理,事件处理,图形用户界面等...
    99+
    2024-04-02
  • CSS3中怎么实现全景图的动画效果
    这篇文章主要为大家展示了“CSS3中怎么实现全景图的动画效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“CSS3中怎么实现全景图的动画效果”这篇文章吧。  ...
    99+
    2024-04-02
  • vue实现轮播图效果的代码
    这篇文章主要介绍“vue实现轮播图效果的代码”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue实现轮播图效果的代码”文章能帮助大家解决问题。1.原理:v-on:click="prev&q...
    99+
    2023-06-27
  • Java实现画图的详细步骤(完整代码)
    一、导入依赖 <dependency> <groupId>net.coobird</groupId> <artifactId...
    99+
    2024-04-02
  • 微信小程序uniapp实现左滑删除效果(完整代码)
    微信小程序uniapp实现左滑删除效果 实现效果 1,列表中侧滑删除 2,删除不同时存在 3,上下滑动与侧滑删除不影响 在本页面引入组件并使用 (文件在文章的最下方附上) 在需要...
    99+
    2024-04-02
  • C++实现AVL树的完整代码
    AVL树的介绍 AVL树是一种自平衡的二叉搜索树,它通过单旋转(single rotate)和双旋转(double rotate)的方式实现了根节点的左子树与右子树的高度差不超过1...
    99+
    2024-04-02
  • vue backtop组件的实现完整代码
    效果: 代码: <template> <div class="back-top"> <div > <img src="im...
    99+
    2024-04-02
  • Java实现抠图片文字或签名的完整代码
    目录java抠图片文字或签名运行原理完整代码java抠图片文字或签名 运行原理 第一步 遍历像素点 BufferedImage image = ImageIO.read(new Fi...
    99+
    2024-04-02
  • Python 三种方法实现截图【详解+完整代码】
    人生苦短 我用python 如何用python实现截屏? 一、方法一 PIL中的ImageGrab模块 使用PIL中的ImageGrab模块简单,但是效率有点低 PIL是Python Imaging...
    99+
    2023-09-03
    python 开发语言 opencv pycharm
  • springboot实现分页功能的完整代码
    目录1.分页功能的作用2.建立测试数据库3.分页功能返回的结果封装4.分页功能代码具体实现4.1数据层4.2业务层4.3控制层5.jqGrid分页插件总结1.分页功能的作用 分页功能...
    99+
    2023-05-16
    springboot分页 springboot分页条件查询 springboot分页功能
  • Vue实现轮播图效果的代码怎么写
    今天小编给大家分享一下Vue实现轮播图效果的代码怎么写的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Vue 过渡Vue 的过...
    99+
    2023-07-04
  • Python实现图像去雾效果的示例代码
    目录修改部分训练测试数据集下载地址修改部分 我利用该代码进行了去雾任务,并对原始代码进行了增删,去掉了人脸提取并对提取人脸美化的部分,如下图 增改了一些数据处理代码,Create_...
    99+
    2024-04-02
  • javascript实现上传图片并预览的效果实现代码
    今天用alphaimageloader滤镜的src属就是其中的主角它将使用绝对或相对url地址指定背景图像。假如忽略此参数,滤镜将不会作用。复制代码 代码如下: <!docty...
    99+
    2022-11-21
    上传图片 预览
  • react实现页面水印效果的全过程
    目录前言1.使用示例2.实现过程3.组件代码总结前言 1.为什么选用svg 而不是cavans? 因为cavans 在高分辨率屏幕下,需要根据 devicePixelRatio做宽高...
    99+
    2024-04-02
  • JS实现图片翻书效果示例代码
    picture.html 复制代码 代码如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <...
    99+
    2022-11-15
    JS 图片翻书
  • Java实现一个顺序表的完整代码
    实现一个顺序表 接口实现 定义一个MyArrayList类,在类中实现以下函数 public class MyArrayList { } 数组的定义 public ...
    99+
    2024-04-02
  • css3代码如何实现图形3d翻转效果
    这篇“css3代码如何实现图形3d翻转效果”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“css3代码如何实现图形3d翻转效果...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作