【发布时间】:2022-01-24 01:45:12
【问题描述】:
我想在three.js 中为网页创建一个菜单,其中每个选项卡都由一个对象(2D 矩形)具体化,我们通过单击右侧矩形访问网站页面。为此,我读到我必须使用当我右键单击鼠标时触发的光线投射器,然后使用相交对象的数组来查看我单击了哪些对象。
我在互联网上尝试了很多教程,但从未成功获得用于右键单击的功能性 raycaster 和 eventListener。 raycast 函数只是从 three.js 文档中复制/粘贴。
这是我的代码(称为 script.js),您知道我做错了什么吗?或者您有什么建议可以改进吗?提前感谢您的帮助!
var camera, scene, rendu;
var geometrie, materiau, mesh;
var controle;
var couleur, plan, onglet1, onglet2, onglet3, onglet4, onglet5, onglet6;
var r, t;
var rayon, souris;
init();
function init() {
r = 3;
t = 1.1;
// ---------- scene et camera --------- //
camera = new THREE.PerspectiveCamera( 70 , window.innerWidth / window.innerHeight , 0.01 , 10 );
camera.position.set( 0 , 0 , 4 );
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
// --------- cube --------- //
//materiau = new THREE.MeshBasicMaterial( { color: 0xffffff});
//geometrie = new THREE.BoxGeometry( t , 3*t , t );
//mesh = new THREE.Mesh( geometrie, materiau );
//scene.add( mesh );
// --------- onglets ---------- //
couleur = new THREE.MeshBasicMaterial( {color: 0x031f3c , side: THREE.DoubleSide } );
plan = new THREE.PlaneGeometry( 0.75 , 0.4 );
onglet1 = new THREE.Mesh( plan , couleur );
onglet1.position.set( 0, 0, r );
scene.add( onglet1 );
onglet2 = new THREE.Mesh( plan , couleur );
onglet2.position.set( r*Math.sqrt(3/4), 0, 0.5*r );
onglet2.rotation.y = Math.PI / 3;
scene.add( onglet2 );
onglet3 = new THREE.Mesh( plan , couleur );
onglet3.position.set( r*Math.sqrt(3/4), 0, -0.5*r );
onglet3.rotation.y = 2 *Math.PI / 3;
scene.add( onglet3 );
onglet4 = new THREE.Mesh( plan , couleur );
onglet4.position.set( 0, 0, -r );
scene.add( onglet4 );
onglet5 = new THREE.Mesh( plan , couleur );
onglet5.position.set( -r*Math.sqrt(3/4), 0, -0.5*r );
onglet5.rotation.y = -2*Math.PI / 3;
scene.add( onglet5 );
onglet6 = new THREE.Mesh( plan , couleur );
onglet6.position.set( -r*Math.sqrt(3/4), 0, 0.5*r );
onglet6.rotation.y = -Math.PI / 3;
scene.add( onglet6 );
// ---------- rendu ------------- //
rendu = new THREE.WebGLRenderer( { antialias: true} );
rendu.setSize( window.innerWidth, window.innerHeight );
rendu.setPixelRatio(window.devicePixelRatio);
rendu.setAnimationLoop( animation );
document.body.appendChild( rendu.domElement );
// ------------- liens sur onglets ------------- //
//window.addEventListener('click', onclick, false);
// ecouter l'event de clic sur la souris
// on ajoute un capteur de rayon qui regarde si on croise un objet de la scene
// si c'est le cas on fait ce qu'on veut en fonction de l'objet
rayon = new THREE.Raycaster();
rendu.domElement.addEventListener( 'click', raycast, false );
}
function animation() {
rendu.render( scene, camera );
controle.update();
}
function raycast ( e ) {
//1. sets the mouse position with a coordinate system where the center
// of the screen is the origin
souris.x = ( e.clientX / window.innerWidth ) * 2 - 1;
souris.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
//2. set the picking ray from the camera position and mouse coordinates
rayon.setFromCamera( souris, camera );
//3. compute intersections
var intersections = rayon.intersectObjects( scene.children );
intersections[0]
}
// ---------- orbitControls --------- //
controle = new THREE.OrbitControls(camera, rendu.domElement);
controle.minPolarAngle = Math.PI / 2;
controle.maxPolarAngle = Math.PI / 2;
controle.autoRotate = true;
controle.autoRotateSpeed = -0.1;
controle.enableZoom = false;
controle.mouseButtons = {
LEFT: THREE.MOUSE.ROTATE,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.ROTATE
}
// ----------- redimensionnement fenetre ------------ //
window.addEventListener('resize', function() {
camera.aspect = window.innerWidth / window.innerHeight ;
camera.updateProjectionMatrix();
rendu.setSize(window.innerWidth, window.innerHeight);
}, false);
let loader = new THREE.GLTFLoader();
loader.load('voiture/scene.gltf', function(gltf){
voiture = gltf.scene.children[0];
//voiture.scale.set(0.5, 0.5, 0.5);
scene.add(gltf.scene);
rendu.render(scene, camera);
});
这是我的 html 代码(称为 index.html)
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<style>
body{margin: 0px;}
canvas{width: 100%; height: 100%;}
</style>
</head>
<body>
<script src="js/build/three.js"></script>
<script src="js/build/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/GLTFLoader.js"></script>
<script src="js/script.js"></script>
</body>
</html>
【问题讨论】:
-
压缩并附加所有依赖项:three.js、three.min.js、OrbitControls.js、GLTFLoader.js、script.js
-
感谢维克托!但它有什么用呢?我不明白
-
用于测试和调试因为我不知道你使用的是三个js的哪个版本...
-
如何将它们压缩到我的代码中?之后我的 html 文件是否能够解压缩以读取它们?
-
前两天我从github下载了三个js文件,估计是最新版本。此外,我认为文件 three.min.js 对任何目的都没有用,因为无论我添加与否,它都不会改变任何东西
标签: javascript three.js onclick addeventlistener raycasting