搭建本地开发环境

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">demo</Link>
</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过程中注意,方法使用箭头函数方便定义和使用变量,定义变量可以直接放在当前实例上。

最新文章

  1. AngularJs $q promise
  2. 友盟SDK实现分享
  3. 此请求的查询字符串的长度超过配置的 maxQueryStringLength 值 --不仅wen.fonfig一个地方需要设置
  4. Discuz! X的CSS加载机制
  5. 新建URL,cookie技术
  6. Yum常用命令及Yum中文手册
  7. ubuntu程序安装方法
  8. javascript中的函数返回值(return)
  9. Javascipt 时间格式化(日期)
  10. HTML5 总结-SVG-5
  11. The List ADT
  12. Git本地操作相关介绍
  13. 开源中文分词工具探析(四):THULAC
  14. ES6解构过程添加一个默认值和赋值一个新的值
  15. postman 请求带cookie
  16. java.lang.NumberFormatException 错误及解决办法
  17. 6.1Python文件的操作(一)
  18. windowsclient开发--为你的client进行国际化
  19. CentOS 配置软raid
  20. [leetcode]139. Word Break单词能否拆分

热门文章

  1. 镜头随人物而动,视频编辑服务让用户稳站C位
  2. conda命令的使用,环境安装,创建环境以Anaconda为例
  3. 超详细干货!Docker+PXC+Haproxy搭建高可用强一致性的MySQL集群
  4. 《SQL Server基础——SQL语句》
  5. redis如何实现数据同步
  6. 七、服务器硬件及RAID配置实战
  7. BUUCTF-乌镇峰会种图
  8. RocketMQ事务消息机制
  9. ssm框架layui分页下标中文乱码,或者请选择中文乱码,提示乱码等
  10. 微服务探索之路04篇k8s增加子节点,metrics资源监控,ingress-nginx域名配置及https配置