当前位置 博文首页 > 文章内容

    使用 React 和 Threejs 创建一个VR全景项目的过程详解

    作者:21344 栏目:未分类 时间:2021-04-06 14:44:33

    最近我在学习使用 React 配合 Three.js 来搭建一个可以浏览720全景图片的项目
    实现的是加载一张 2:1 的720全景
    分享一下我的创建过程

    一、搭建框架并安装需要的插件

    npx create-react-app parano	// 创建一个 React 项目
    npm install -S typescript	// 安装 typescript,这个是类型辅助插件,与全景项目关系不大
    npm install -S @types/three	// 安装 typescript 支持的 three.js 插件

    二、创建 Pano 组件

    Pano 组件用来加载720全景图

    import React from 'react'
    import * as THREE from 'three'	// 引入 Three.js 插件
    import banner from './img/playground.jpg'	// 引入全景图
    // props 类型声明接口
    interface MyProps {
    }
    // state 类型声明接口
    interface MyState {
    }
    class Pano extends React.Component<MyProps, MyState> {
      renderer: any = new THREE.WebGLRenderer()	// 创建一个渲染器
      scene: any = new THREE.Scene()	// 创建一个场景
      camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)	// 创建一个摄像机
      geometry = new THREE.SphereBufferGeometry(100, 60, 40)	// 创建一个球形的容器,用于贴全景图上去
      material: any	// 贴图材质
      mesh: any
      constructor(props: any) {
        super (props)
        this.state = {}
      }
      componentDidMount () {
        this.geometry.scale(-1, 1, 1)
        let texture = new THREE.TextureLoader().load(banner)
        this.material = new THREE.MeshBasicMaterial({map: texture})
        this.mesh = new THREE.Mesh(this.geometry, this.material)
        this.renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(this.renderer.domElement)
        this.scene.add(this.mesh)
        this.camera.position.z = 0
        window.addEventListener('resize', this.onWindowResize, false)
        this.animate()
      }
    	// 实现窗口大小改变的时候改变全景图的显示大小
      onWindowResize = () => {
        this.camera.aspect = window.innerWidth / window.innerHeight
        this.camera.updateProjectionMatrix()
        this.renderer.setSize(window.innerWidth, window.innerHeight)
      }
    	// 逐帧渲染
      animate = () => {
        requestAnimationFrame(this.animate)
        this.mesh.rotation.y += 0.001
        this.renderer.render(this.scene, this.camera)
      }
      render () {
        return (
          <div></div>
        )
      }
    }
    export default Pano

    三、将 Pano 组件添加到 App 组件中

    import React from 'react';
    import './App.css';
    import Pano from './pano';
    
    function App() {
     return (
      <div className="App">
       <Pano />
      </div>
     );
    }
    
    export default App;

    此时在项目目录中执行 npm run start 即可看到效果