在单独使用三个js应用程序后,我想让这个三个js应用程序成为我的React应用程序中的一个组件。
我需要覆盖多个场景,所以我创建了一个实现场景,相机,渲染器的ThreeApp函数并将其添加到DOM中。所以我试着让很多东西可以重复使用。
在关注this answer后,我设法在我的反应应用程序中获得了一个带有旋转立方体的三个js场景。成功!因为我已经做了一个正常运行的OOP(?)实现而没有反应,所以我直接进入。
现在我的应用程序中有一个渲染的画布,但其中的对象没有渲染。但是我可以看到三个js检查员扩展中的场景。如果我登录了动画/更新功能,那么它们都会被激活。
这是从最初工作的SO answer复制的反应组件。
import React, { Component } from 'react'
import * as THREE from 'three'
import testCube from "./viz/testCube"
import VizHandler from './VizHandler'
class Visualizer extends Component {
constructor(props) {
super(props)
this.start = this.start.bind(this)
this.stop = this.stop.bind(this)
this.animate = this.animate.bind(this)
}
componentDidMount() {
const vizHandler = this.vizHandler = new VizHandler();
vizHandler.init(this.mount);
this.start()
}
componentWillUnmount() {
this.stop()
// this.mount.removeChild(threeApps['vizholder'].getRenderer().domElement)
// vizHandler.unmount(this.mount);
}
start() {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate)
}
}
stop() {
cancelAnimationFrame(this.frameId)
}
animate() {
this.vizHandler.update(); // update / animate stuff in here
this.vizHandler.render()
this.frameId = window.requestAnimationFrame(this.animate)
}
render() {
return (
<div
// style={{ width: '400px', height: '400px' }}
ref={(mount) => { this.mount = mount }}
/>
)
}
}
export default Visualizer
我在VizHandler函数/类
中处理多个threejs场景/画布import * as THREE from "three";
import threeApp from "./threeApp";
import WhiteRing from "./viz/WhiteRing";
import testCube from "./viz/testCube";
import Bars from "./viz/Bars";
const VizHandler = function () {
var threeApps = [];
var rings = new WhiteRing();
var bars = new Bars();
var cube = new testCube();
function init(mount) {
threeApps['vizholder'] = new threeApp();
// threeApps['overlay'] = new threeApp();
threeApps['vizholder'].init(mount, 'VizHolder') ;
// threeApps['overlay'].init(mount, 'Overlay');
window.scene = threeApps['vizholder'].getScene();
window.THREE = THREE;
const vizHolder = threeApps['vizholder'].getVizHolder();
rings.init( vizHolder );
bars.init( vizHolder );
cube.init( vizHolder );
}
function update() {
rings.update();
bars.update();
cube.update();
}
function render() {
threeApps["vizholder"].render();
}
return {
init: init,
update: update,
render: render,
getVizHolder: function( name ) {
if ( name ) return threeApps[name].getVizHolder();
else return threeApps['vizholder'].getVizHolder();
},
getRenderer: function( name ) {
if ( name ) return threeApps[name].getRenderer();
else return threeApps['vizholder'].getRenderer();
},
getThreeApps: function() {
return threeApps
},
};
};
这是我尝试渲染的最基本的立方体。
import * as THREE from 'three';
const testCube = function () {
let cube;
function init (vizHolder) {
const groupHolder = new THREE.Object3D();
groupHolder.name = "TemplateViz";
vizHolder.add(groupHolder);
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: '#ffffff' })
cube = new THREE.Mesh(geometry, material)
cube.name = "TESTCUBE";
groupHolder.add(cube);
vizHolder.add(groupHolder);
}
function update() {
cube.rotation.x += 0.01
cube.rotation.y += 0.01
}
return {
init: init,
update: update,
}
};
export default testCube;
所有这一切的结果都是dom中的渲染器元素,它不会将我的元素渲染到场景中。我可以更改渲染器颜色并更新场景中的对象,但我无法显示它们。
编辑:在我更简化的答案here解决问题后,我忘了发布错误最终发生的1个重要文件。我制作场景,渲染器和相机的三个App类。下面的代码是非工作代码。
import * as THREE from "three";
function threeApp() {
let camera, scene, renderer;
let groundLight, skyLight, hemiLight;
let vizHolder;
let objName;
let renderColor = '#909009';
function init(mount, name) {
objName = name;
this.holderName = name;
renderer = new THREE.WebGLRenderer({
// antialias: true,
// alpha: true
});
renderer.setSize(800, 600);
renderer.domElement.className = "renderer";
mount.appendChild(renderer.domElement);
//3D SCENE
camera = new THREE.PerspectiveCamera(70, 800 / 600, 1, 3000);
camera.position.z = 1000;
camera.name = "camera";
scene = new THREE.Scene();
// window.THREE = THREE;
scene.name = name + " scene";
console.log( 'name', name );
if ( name == "VizHolder") {
window.scene = scene;
}
camera.lookAt(scene);
scene.fog = new THREE.Fog(0xffd8e5, 1000, 3000);
scene.add(camera);
//INIT VIZ
vizHolder = new THREE.Object3D();
vizHolder.name = name;
scene.add(vizHolder);
}
function update () {
render();
}
function render() {
renderer.render(scene, camera);
}
function onResize () {
var renderW = window.innerWidth;
var renderH = window.innerHeight;
camera.aspect = renderW / renderH;
camera.updateProjectionMatrix();
renderer.setSize(renderW, renderH);
}
return {
init: init,
render: render,
onResize: onResize,
getVizHolder: function() {
return vizHolder;
},
getCamera: function() {
return camera;
},
getScene: function() {
return scene;
},
getRenderer: function() {
return renderer;
},
setRenderColor: setRenderColor
}
};
export default threeApp