【发布时间】:2018-12-17 20:46:41
【问题描述】:
当我动态加载 Three.js 时,仍然找不到变量 THREE。
我已经使用create-react-app 创建了一个 React 项目,并将三个 js 文件复制到 public 文件夹中。结构如下:
src
public
├── js
│ └── threejs
│ ├── Detector.js
│ ├── OrbitControls.js
│ ├── postprocessing
│ │ ├── BloomPass.js
│ │ ├── ShaderPass.js
│ │ └── ...
│ ├── shaders
│ │ ├── BasicShader.js
│ │ ├── BleachBypassShader.js
│ │ ├── ....
│ ├── three.js
│ └── three.min.js
我创建了以下类,它可以动态加载three.js 和任何属于examples/js 文件夹的文件并触发onLoaded 回调:
// Dependencies
import React from 'react';
export default class ThreeJsLoader extends React.Component {
constructor(props) {
super(props);
this.unloaded = [
'/js/threejs/three.js',
'/js/threejs/OrbitControls.js'
];
this.loaded = [];
}
loadScript(address) {
let script = document.createElement('script');
script.setAttribute('type', 'text/javascript'); // optional
script.setAttribute('src', address);
script.onload = () => {
this.loaded.push(address);
this.checkLoaded();
};
document.getElementsByTagName('head')[0].appendChild(script);
}
checkLoaded() {
if(this.loaded.length >= this.unloaded.length) {
if(this.props.onLoaded) {
this.props.onLoaded();
}
}
}
componentDidMount() {
while(true) {
let script = this.unloaded.shift();
let script_path = `${process.env.PUBLIC_URL}${script}`;
if(script) {
this.loadScript(script_path);
}
else {
break;
}
}
}
render() {
return null;
}
}
这就是脚本的使用方式:
import React from 'react';
import ThreeJsLoader from './threejs_loader';
export default class PageBackground extends React.Component {
constructor(props) {
super(props);
this.background_ref = React.createRef();
}
loadScene() {
let scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );
let renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
this.background_ref.current.appendChild( renderer.domElement );
let camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 400, 200, 0 );
// controls
let controls = new THREE.OrbitControls( camera, renderer.domElement );
}
render() {
return (
<div>
<ThreeJsLoader onLoaded={ () => this.loadScene() } />
<div ref={this.background_ref} > </div>
</div>
);
}
}
我已经测试了代码并正确加载了脚本。但是,我收到以下错误:
./src/page_background.jsx
Line 36: 'THREE' is not defined no-undef
Line 37: 'THREE' is not defined no-undef
【问题讨论】:
-
你检查过你的 page_background.jsx 了吗?看起来您需要在该文件中定义三个常量。
-
THREE 变量定义在three.js 中,由 ThreeJsLoader 动态加载。在另一个类中,我等待 ThreeJsLoader 完成加载,然后调用三个变量
标签: javascript reactjs three.js create-react-app