• reactjs中使用threejs从0到1


    搭建本地开发环境

    npx create-react-app react-three-demo
    
    • 删除掉新项目中 src/ 文件夹下的所有文件。(不要删除整个 src 文件夹,删除里面的源文件。)

    • 安装路由依赖包和threejs依赖包

    # tips: 注意版本兼容问题
    npm install react-router@5 react-router-dom@5
    
    npm install --save three
    
    • 按照下面目录结构创建文件
    -public
    └─src
        ├─assets
        │  └─styles
        ├─routers
        │  └─index.js
        └─views
        │  ├─home.js
        │  └─demo.js
        ├─index.js // 入口文件
        ├─app.js // 主文件
    

    组件和路由文件

    • 路由文件
    import { Route } from 'react-router-dom'
    import Index from '../views/index'
    import Demo from '../views/demo'
    
    // 路由配置
    const Routes = [
      {
        path: '/',
        exact: true,
        component: Index
      },
      {
        path: '/Demo',
        exact: true,
        component: Demo
      }
    ]
    
    function AppRouter() {
      return (
        <main>
          {Routes.map((item, index) => {
            return <Route key={index} path={item.path} exact={item.exact} component={item.component}>Route>
          })}
        main>
      )
    }
    
    export default AppRouter
    
    
    • 入口文件index.js
    import React from 'react'
    import ReactDOM from 'react-dom/client'
    
    import './assets/styles/base.css'
    import App from './App'
    
    const root = ReactDOM.createRoot(document.getElementById('root'))
    // 注意,不要使用严格模式去渲染,否则会导致 componentDidMount 钩子执行两次
    root.render(<App />)
    
    
    • app.js
    import { BrowserRouter as Router, Link } from 'react-router-dom'
    import AppRouter from './routers'
    
    function App() {
      return (
        <Router>
          <div className="App">
            <nav>
              <Link to="/">首页Link>
              <Link to="/Demo">demoLink>
            nav>
    
            <AppRouter>AppRouter>
          div>
        Router>
      )
    }
    
    export default App
    
    
    • 首页 home.js
    import { Component } from 'react'
    import * as THREE from 'three'
    // import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
    
    export default class Index extends Component {
      render() {
        return <div id="stage">div>
      }
    
      /**
       * @Description: 组件挂载完成
       * @return {*}
       */
      componentDidMount() {
        this.init()
        this.animate()
      }
    
      /**
       * @Description: 初始化
       * @return {*}
       */
      init = () => {
        this.scene = new THREE.Scene()
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - 33), 0.1, 1000)
    
        this.renderer = new THREE.WebGLRenderer()
        this.renderer.setSize(window.innerWidth, window.innerHeight - 33)
        document.getElementById('stage').appendChild(this.renderer.domElement)
    
        const geometry = new THREE.BoxGeometry(1, 1, 1)
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
        this.cube = new THREE.Mesh(geometry, material)
        this.scene.add(this.cube)
    
        this.camera.position.z = 5
      }
    
      /**
       * @Description: 旋转动画
       * @return {*}
       */
      animate = () => {
        requestAnimationFrame(this.animate)
        this.cube.rotation.x += 0.01
        this.cube.rotation.y += 0.01
        this.renderer.render(this.scene, this.camera)
      }
    }
    

    package.json文件

    {
      "name": "react-three-demo",
      "version": "0.1.0",
      "private": true,
      "scripts": {
        "dev": "set PORT=8888 && react-scripts start",
        "build": "react-scripts build"
      },
      "dependencies": {
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-router": "^5.3.3",
        "react-router-dom": "^5.3.3",
        "react-scripts": "5.0.1",
        "three": "^0.143.0",
      }
    }
    

    备注

    搞这个小demo的过程中遇到一些问题,总结如下:

    1. nodejs版本要足够新,否则可能创建项目不成功

    2. npx create-react-app创建项目报错(不报错的忽略)

      npm ERR! code ENOLOCAL
      npm ERR! Could not install from "Files\nodejs\node_cache\_npx\1452" as it does not contain a package.json file.
      
      npm ERR! A complete log of this run can be found in:
      npm ERR!     C:\Program Files\nodejs\node_cache\_logs\2022-08-04T14_46_10_318Z-debug.log
      Install for create-react-app@latest failed with code 1
      
      解决方法:
      检查本地用户下的 .npmrc 文件配置,去掉config配置,重新创建项目即可。
      如果还不行那就重新安装node吧
      
    3. 路由报错,页面空白

      Uncaught Error: Invariant failed: You should not use <Switch> outside a <Router>
      
      那可能是react-router和react-router-dom的版本不兼容,或者是路由位置放错了。
      本文使用的 v5 版本,写法可以参考本文路由文件也可自己尝试其他方式。
      
    4. threejs创建的3D图形,canvas渲染出现两个

      // 注意入口文件中使用的是严格模式,导致 componentDidMount 钩子执行两次,init函数执行两次造成的
      // 解决方法:要么去掉严格模式,要不操作dom控制只有一个canvas元素,本文使用第一种方法
      root.render(
        <React.StrictMode>
          <App />
        React.StrictMode>
      )
      
      // 解决方法一
      root.render(<App />)
      
    5. 使用threejs 做demo过程中注意,方法使用箭头函数方便定义和使用变量,定义变量可以直接放在当前实例上。

  • 相关阅读:
    一文理解分布式开发中的服务治理
    【数据结构】哈希表
    Java22重磅发布!!!!卷不动了,真的卷不动了。。。。
    特殊类设计[下] --- 单例模式
    layui表格删除最后一页数据时,不会刷新到前一页问题:
    电路原理解题笔记(一)
    B树的定义和特点
    JVM-虚拟机的故障处理与调优案例分析
    【iOS】JSON解析
    Mybatis的XML配置文件
  • 原文地址:https://www.cnblogs.com/codebook/p/16551668.html