在OOP实现后,三个js不在场景中渲染对象

时间:2018-01-11 23:46:47

标签: javascript reactjs three.js

在单独使用三个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

0 个答案:

没有答案