Raycaster显示一个渲染

时间:2019-03-14 10:43:42

标签: reactjs three.js raycasting

我使用Threejs,我想创建一个函数来在单击Sphere时显示描述性卡片( Satllite.js Render())。 ( Satellite.js

/********** Imports **********/
import React, { PureComponent } from 'react';
import * as THREE from 'three';

import satData from '../data/sat.json';

export class Satellites extends PureComponent {

  constructor(props) {
    super(props)
    this.state = { open: true }

    this.x = {};
    this.mouse = {};
    this.raycaster = new THREE.Raycaster();
    this.mouse = new THREE.Vector2();

  }

  onDocumentMouseDown = event => {
    event.preventDefault()
    this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
    this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
    // find intersections
    this.raycaster.setFromCamera(this.mouse, this.props.camera)
    this.intersects = this.raycaster.intersectObjects(
      this.scene.className("card"),
      false
    )
    if (this.intersects.length > 0) {
      if (this.intersects[0].object.callback)
        this.intersects[0].object.callback()
      this.intersects[0].className(".card")

      this.particle = new THREE.Sprite(this.particleMaterial)
      this.particle.position.copy(this.intersects[0].point)

      this.particle.scale.x = this.particle.scale.y = 16
      this.props.scene.add(this.particle)
    }
  }

  componentDidMount() {
    // Satellite Sphere
    // this.geometry = new THREE.SphereGeometry( this.props.data.r, 32, 32 );
    this.geometry = new THREE.SphereGeometry(10, 32, 32)
    this.material = new THREE.MeshBasicMaterial({ color: 0xffff00 })
    this.sphere = new THREE.Mesh(this.geometry, this.material)
    this.sphere.callback = function() {
      console.log('Toto!')
    }
    this.sphere.position.set(50, 50, 50)
    this.props.scene.add(this.sphere)
    document.addEventListener('mousedown', this.onDocumentMouseDown, true)
  }

  // componentDidUpdate() {
  //   // update satelite pos.
  //   const radius = 10;
  //   const scale = radius * 1;
  //   this.sphere.scale.x = scale;
  //   this.sphere.scale.y = scale;
  //   this.sphere.scale.z = scale;
  // }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.onDocumentMouseDown);
  }

  render() {
    return (
      <div>
        {satData.map((satDetail, index) => {
          return <div key={index} className="card">
            <h2>{satDetail.satName.toUpperCase()}</h2>
            <div className="cardImg" >
              <img src={satDetail.satImg} alt={satDetail.satAlt} />
            </div>
            <div>
              <p>Altitude : <span>{satDetail.alt}</span> km</p>
              <p>Longitude : <span>{satDetail.long}</span> °</p>
              <p>Latitude : <span>{satDetail.lat}</span> °</p>
            </div>
            <button onClick={this.closeModal}>Fermer</button>
          </div>
        })}
      </div>
    )
  }
}

更多详细信息here

我有一个显示白色正方形的教程代码,但我想显示我的div“ .card” ,它位于“渲染” 中 方法是什么?

感谢帮助!

1 个答案:

答案 0 :(得分:1)

此答案涉及许多主题,基本上,您需要:

  1. 用光线投射鼠标单击并找到对象的交点,
  2. 通过拾取的对象获取信息,
  3. 如果选择了对象,则显示它;如果鼠标未选择任何对象,则隐藏。

在此处进行测试:http://jsfiddle.net/mmalex/9k4qbL8s/

let cardShown = false;

function showCard(userText) {
  var divElement = $("#card");

  if (divElement) {
    if (!cardShown) {
      divElement.css({
        display: "block",
        opacity: 0,
        height: "0px"
      });
    }

    divElement.text("Object color: " + userText);

        if (!cardShown) {
      setTimeout(function() {
        divElement.css({
          opacity: 1,
          height: "16px"
        });
      }, 25);
    }

    cardShown = true;
  }
}

function hideCard() {
  var divElement = $("#card");
  if (divElement) {
    divElement.css({
      height: "0px",
      opacity: 0
    });
    cardShown = false;
  }
}

var scene = new THREE.Scene();
var raycaster = new THREE.Raycaster();

//create some camera
camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 5;
camera.position.y = 5;
camera.position.z = 5;
camera.lookAt(0, 0, 0);

var controls = new THREE.OrbitControls(camera);

var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0x595959));
document.body.appendChild(renderer.domElement);

// white spotlight shining from the side, casting a shadow
var spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI / 6);
spotLight.position.set(4, 10, 7);
scene.add(spotLight);

// collect objects for raycasting, 
// for better performance don't raytrace all scene
var clickableObjects = [];

var colors = new RayysWebColors();
for (let k = 0; k < 12; k++) {
  var size = 0.5;
  var geometry = new THREE.BoxGeometry(size, 0.2, size);
  var randomColor = colors.pickRandom();
  var material = new THREE.MeshPhongMaterial({
    color: randomColor.hex,
    transparent: true,
    opacity: 0.75
  });
  var cube = new THREE.Mesh(geometry, material);
  cube.userData.userText = randomColor.name;
  cube.applyMatrix(new THREE.Matrix4().makeTranslation(k % 3, 0, Math.floor(k / 3) - 1));
  scene.add(cube);
  clickableObjects.push(cube);
}

function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
}

// this will be 2D coordinates of the current mouse position, [0,0] is middle of the screen.
var mouse = new THREE.Vector2();

var clickedObj; // this objects is hovered at the moment

// Following two functions will convert mouse coordinates
// from screen to three.js system (where [0,0] is in the middle of the screen)
function updateMouseCoords(event, coordsObj) {
  coordsObj.x = ((event.clientX - renderer.domElement.offsetLeft + 0.5) / window.innerWidth) * 2 - 1;
  coordsObj.y = -((event.clientY - renderer.domElement.offsetTop + 0.5) / window.innerHeight) * 2 + 1;
}

function onMouseUp(event) {
  updateMouseCoords(event, mouse);

  latestMouseProjection = undefined;
  clickedObj = undefined;

  raycaster.setFromCamera(mouse, camera); {
    var intersects = raycaster.intersectObjects(clickableObjects);

    if (intersects.length > 0) {
      latestMouseProjection = intersects[0].point;
      clickedObj = intersects[0].object;
      showCard(clickedObj.userData.userText);
    } else {
      clickedObj = undefined;
      hideCard();
    }
  }
}

window.addEventListener('mouseup', onMouseUp, false);

animate();