首页 > 解决方案 > 打字稿中带有raycaster的three.js(鼠标悬停)

问题描述

我是three.js的初学者。我已经在 java 脚本https://jsfiddle.net/wilt/52ejur45/中实现了这个带有鼠标悬停的 raycaster 示例。但是,当我尝试在打字稿中执行此操作时,它不起作用。带有鼠标悬停的光线投射器仅在使用打字稿中的轨道控制器单击和拖动时才有效。我提供了 java 脚本和 typescript 代码。谁能帮我找出解决办法。

Java script code : 

<!DOCTYPE html>
<html lang="en">

<head>
    <title>three.js raycaster</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="main.css">
<meta name="referrer" content="origin-when-cross-origin" />

        <script src="https://threejs.org/build/three.min.js"></script>
        <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
    <script type="module">


        var camera, scene, renderer;
        var mesh,controls;
        var cube;
        var mouse = {
            x: 0,
            y: 0
        },
        INTERSECTED;

        init();
        animate();

        function init() {

            camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
            camera.position.z = 500;

            scene = new THREE.Scene();

            var pointlight = new THREE.PointLight(0xffffff,0.5);
            var light = new THREE.DirectionalLight(0xffffff, 0.4);
            camera.add( pointlight, light);
            light.position.set( 10, 10, 0 );
            pointlight.position.set( 10, 10, 0 );
            scene.add(camera);

            var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
            for (var i = 0; i < 200; i++) {
                var object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
                object.position.x = Math.random() * 800 - 400;
                object.position.y = Math.random() * 800 - 400;
                object.position.z = Math.random() * 800 - 400;
                scene.add(object);
            }

            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setClearColor("#00a9d4", 1);
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);
            var controls = new THREE.OrbitControls(camera, renderer.domElement);
            window.addEventListener('resize', onWindowResize, false);
            document.addEventListener('mousemove', onDocumentMouseMove, false);

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);

        }

        function onDocumentMouseMove(event) {
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
            console.log(mouse.x,mouse.y);
        }

        function animate() {

            requestAnimationFrame(animate);
            render();
            update();

        }

        function update() {
            var vector = new THREE.Vector3(mouse.x, mouse.y, 1);
            console.log(vector);
            vector.unproject(camera);
            var ray = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
            var intersects = ray.intersectObjects(scene.children);
            if (intersects.length > 0) {
                console.log(intersects.length);
                if (intersects[0].object != INTERSECTED) {
                    if (INTERSECTED)
                        INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
                    INTERSECTED = intersects[0].object;
                    INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
                    INTERSECTED.material.color.setHex(0xffff00);
                }
            } else {
            }

        }

        function render() {
            renderer.render(scene, camera);
        }

    </script>

</body>

</html>
Typescript code:

import { Component, ViewChild, ElementRef, HostListener } from '@angular/core';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'mousehover';

  @ViewChild('canvas', null)
  private canvasRef: ElementRef;

  public mouse = {
    x: 0,
    y: 0
  };

  INTERSECTED;
  public camera; scene; controls;
  public raycaster;
  public renderer; directionallight;




  private getAspectRatio(): number {
    let height = this.canvas.clientHeight;
    if (height === 0) {
      return 0;
    }
    return this.canvas.clientWidth / this.canvas.clientHeight;
  }

  private get canvas(): HTMLCanvasElement {
    return this.canvasRef.nativeElement;
  }

  ngOnInit() {
    this.init();
    this.animate();
  }

  init() {
    this.canvas.style.height = window.innerHeight + "px";
    this.canvas.style.width = window.innerWidth + "px";
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
    this.camera.position.x = 0;
    this.camera.position.y = 0;
    this.camera.position.z = 100;
    this.directionallight = new THREE.DirectionalLight(0xffffff, 1);
    this.directionallight.position.set(1, 1, 1).normalize();
    this.camera.add(this.directionallight);
    this.scene.add(this.camera);
    var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
    for (var i = 0; i < 200; i++) {
      var object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
      object.position.x = Math.random() * 800 - 400;
      object.position.y = Math.random() * 800 - 400;
      object.position.z = Math.random() * 800 - 400;
      this.scene.add(object);
    }
    this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvas });
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.setClearColor("#79bff3", 1);
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    document.addEventListener('mousemove', this.onDocumentMouseMove, false);
  }

  onDocumentMouseMove(event) {
    this.mouse = new THREE.Vector2();
    this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  }

  animate() {
    try {
      window.requestAnimationFrame(() => this.animate());
      this.render();
      this.update();
    }
    catch (err) {
      console.log("animate error. " + err.message);
    }
  }

  update() {
    var vector = new THREE.Vector3(this.mouse.x, this.mouse.y, 1);
    vector.unproject(this.camera);
    var ray = new THREE.Raycaster(this.camera.position, vector.sub(this.camera.position).normalize());
    var intersects = ray.intersectObjects(this.scene.children);
    if (intersects.length > 0) {
      console.log(intersects.length);
      if (intersects[0].object != this.INTERSECTED) {
        if (this.INTERSECTED)
          this.INTERSECTED.material.color.setHex(this.INTERSECTED.currentHex);
        this.INTERSECTED = intersects[0].object;
        this.INTERSECTED.currentHex = this.INTERSECTED.material.color.getHex();
        this.INTERSECTED.material.color.setHex(0xffff00);
      }
    } else {
    }
  }

  render() {
    this.renderer.render(this.scene, this.camera);
  }

}

标签: typescriptthree.js3d

解决方案


推荐阅读