在react和three.js中拖放对象

时间:2019-06-08 23:35:25

标签: javascript reactjs three.js drag-and-drop jsx

我一直在尝试在React和Three.js中实现一个简单的拖放解决方案。我在平面上手动添加对象,并尝试沿Y和Z方向将它们拖放到平面上。

在Internet上,关于React中拖放的示例非常有限,而且看起来还需要另一个Node模块。我花了几个小时才弄清楚。

我点击了此链接https://codepen.io/kaolay/pen/bqKjVz,但它很复杂,没有注释。

import React, { Component } from 'react';
import * as THREE from 'three';
import NavBar from "./navbar.js";
import DragControls from 'drag-controls'
import {Button, Row, Col, Container} from "react-bootstrap";
const OrbitControls = require("three-orbit-controls")(THREE);
var raycaster = new THREE.Raycaster();
var OBJLoader = require('three-obj-loader');
var mouse = new THREE.Vector2();
OBJLoader(THREE);

export default class ThreeEntryPoint extends Component {
  constructor(){
    super();
    this.camera = "";
    this.scene  = "";
    this.renderer = "";
    this.world = "";
    this.ground = "";
    this.controls = "";
    this.container = "";
    this.state ={
      toggle: false,
      currentSandBoxState:""
    };
    this.itemList = [];
    this.lastAddedXPosition = 0;
    this.lastAddedZPosition = 0;
    this.selectedObject= "";
    this.offset = new THREE.Vector3();
  }


  setSandboxState = (e) => {
    console.log(e);
    this.setState({currentSandBoxState : e});
  }


  addTree = (x, z) => {
    this.THREE = THREE;
    var objLoader = new this.THREE.OBJLoader()
    this.setState({toggle: !this.state.toggle}) ;
    var this_ = this;

    objLoader.load('https://swamp-back.s3.eu-central-1.amazonaws.com/objects/lowpolytree.obj', function(object){
      object.position.y = 4;
      object.position.z = z + this_.lastAddedZPosition;
      object.position.x = x + this_.lastAddedXPosition;
      this_.lastAddedXPosition++;
      this_.lastAddedZPosition++;
      object.scale.set(2, 2, 2);
      this_.scene.add(object);
    },function(xhr) {
      }, function(error) {
        console.log(error);
    });
  }


  setCamera = (camera) => {
    camera.position.z = 100;
        camera.position.y = 30;
    camera.lookAt( new THREE.Vector3(0,0,0) );
    camera.add(new THREE.PointLight(0xffffff,0.7))
  }



  componentDidMount(  ) {
    this.Three = THREE;
    var container_ = document.getElementById("container-canvas");
    this.contaier = container_;
    const width  = window.innerWidth - 300;
    const height = window.innerHeight - 200;

    this.scene    = new THREE.Scene();
    this.camera   = new THREE.PerspectiveCamera( 45, width/height, 10, 1000 );
    this.renderer = new THREE.WebGLRenderer();
    this.renderer.setClearColor(0xfffffff);
    this.controls = new OrbitControls(this.camera, this.canvas);
    this.controls.target.set(0, 5, 0);
    this.controls.rotateSpeed = 1.0;
    this.controls.zoomSpeed   = 1.2;
    this.controls.panSpeed    = 0.8;

    this.renderer.setSize( width, height );
    container_.appendChild( this.renderer.domElement );

    var geometry     = new THREE.BoxGeometry( 250, 1, 40 );
    var material     = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    var cube         = new THREE.Mesh( geometry, material );
    var ambientLight = new THREE.AmbientLight( 0x0f0f0f );
    this.world        = new THREE.Object3D();


    this.ground = new THREE.Mesh(
            new THREE.BoxGeometry(100,1,40),
            new THREE.MeshLambertMaterial( {color:"green"})
        );

        this.ground.position.y = 0 // top of base lies in the plane y = -5;
    this.scene.add( this.world );

    let this_ = this;
    var animate = function () {
      requestAnimationFrame( animate );
      this_.controls.update();
      this_.renderer.render( this_.scene, this_.camera );
    };

    this.addTree(10, 11);
    this.scene.add(this.ground);
    this.scene.add( ambientLight );
    this.scene.add(new THREE.DirectionalLight(0xffffff,0.5));
    this.setCamera(this.camera);

    animate();
  }


  render(){
    return (
      <Container>
        <NavBar passState={this.setSandboxState}/>
          <Row id="container-canvas" style={{display:"flex", alignItems:"center", justifyContent:"center"}}>
        </Row>
      </Container>
    );
  }
};

我已经设置了最少的代码来渲染布局并向其中添加一个对象。我做了很多尝试,以找到用于抓取控件的节点模块,但找不到任何模块。

有人可以提供一种简单的解决方案来在X和Z轴上拖放对象吗?这是一个筋疲力尽的搜索,或者它只是在我不被注意之前就出现了。我是three.js的新手,也很乐意做出任何反应,非常感谢。

0 个答案:

没有答案