typescript - 打字稿中带有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);
}
}
解决方案
推荐阅读
- python - 使用谷歌地图 API 计算熊猫数据帧中经纬度之间的距离
- javascript - javascript/typescript 函数参数语法
- html - 块大小和文本居中
- react-native - 反应原生隐藏/打开所有控制台日志
- spring-boot - Keycloak Spring 在登录和编程注销之前启动
- python - 使用 sqlalchemy 获取访问数据库中表的名称
- android - 如何获取android中活动的父活动链(在运行时)?
- python - 从 Wikinews 获取每日新闻提要
- database - 如何确定在 Firebase 中创建条目的用户?
- c++ - 如何在 MFC 中读取 MP3 文件的 Title 和 ArtistName