import * as THREE from 'three'; let moveFlag = false; var point = new THREE.PointLight(0xffffff, 1, 100); // point.position.set(0, 0, 0); const sphereSize = 0.5;//辅助对象的大小 const pointLightHelper = new THREE.PointLightHelper(point, sphereSize, 0xFF00FF); // const axisHelper = new THREE.AxesHelper(5); export default function pointLight(vis) { let domContainer = document.getElementById('threeContainer'); if (vis) { window.controls.enableRotate = false; domContainer?.addEventListener('mousedown', onmousedown); domContainer?.addEventListener('mousemove', onmousemove); domContainer?.addEventListener('mouseup', onmouseup); window.controls.addEventListener("change", onPointerMove); // 增加点光源 window.threescene.add(point); // 需要捕获鼠标点击未松开时的位置作为点光源的位置 window.threescene.add(pointLightHelper); } else { // 卸载点光源 } } // 写个方法开始获取鼠标按下事件,然后将坐标位置转化为三维坐标 // 进入了这个页面就不再触发模型拖动事件了 function onmousedown(event) { moveFlag = true; console.log(event, 'mousedown事件'); } function onmousemove(event) { if (moveFlag) { console.log('mousemove事件'); const mouseX = event.clientX; const mouseY = event.clientY; const vector = new THREE.Vector3( (mouseX / window.innerWidth) * 2 - 1, -(mouseY / window.innerHeight) * 2 + 1, 0.5 ); vector.unproject(window.camera); const dir = vector.sub(window.camera.position).normalize(); const distance = -window.camera.position.z / dir.z; const pos = window.camera.position.clone().add(dir.multiplyScalar(distance)); console.log(pos,'pos'); point.position.copy(pos); console.log(point.position,'point'); pointLightHelper.light = point; } } function onmouseup() { moveFlag = false; console.log('mouseup事件'); } function onPointerMove() { // 如何取消调拖拽事件,而取消查看点光源后再打开 // 操作render函数吗 console.log('change事件'); }
时间: 2024-02-03 19:03:03 浏览: 82
根据您提供的代码,我发现在计算鼠标位置时,使用了窗口的大小来归一化鼠标位置,但是没有考虑到窗口的边框和标题栏等因素,可能导致计算出来的鼠标位置与实际位置存在偏移。您可以尝试将计算鼠标位置的代码改为:
```
const rect = domContainer.getBoundingClientRect();
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
```
其中,`getBoundingClientRect()`方法可以获取到窗口的边框和标题栏等信息,从而准确计算出鼠标位置。同时,您还需要注意在计算光线方向时,是否使用了正确的坐标系,例如使用屏幕坐标系或者使用世界坐标系。如果您仍然存在问题,可以提供更多的细节或者错误提示,我可以帮您进一步定位问题。
相关问题
this.scene = new THREE.Scene(); // camera let aspect = window.innerWidth / window.innerHeight; let d = 20; this.camera = new THREE.OrthographicCamera(-d * aspect, d * aspect, d, -d, -100, 1000); this.camera.position.x = 2; this.camera.position.y = 2; this.camera.position.z = 2; this.camera.lookAt(new THREE.Vector3(0, 0, 0)); //light this.light = new THREE.DirectionalLight(0xffffff, 0.5); this.light.position.set(0, 499, 0); this.scene.add(this.light); this.softLight = new THREE.AmbientLight(0xffffff, 0.4); this.scene.add(this.softLight); window.addEventListener('resize', () => this.onResize()); this.onResize();
这段代码继续初始化了Three.js场景中的相机和灯光。首先,它创建了一个`OrthographicCamera`对象,并设置了它的位置和方向,使其从斜上方俯瞰场景。然后,它创建了一个白色的`DirectionalLight`对象,表示一个定向光源,它的强度为0.5。这个光源被放置在场景正上方,并向下照射。接着,它创建了一个白色的`AmbientLight`对象,表示一个环境光源,它的强度为0.4。最后,它注册了一个监听器,在窗口大小改变时自动调用`onResize`函数来更新相机和渲染器的尺寸。
<!DOCTYPE html> <html lang="en"> <head> <title>Load Obj and Mtl file with texture using Three.js</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { margin: 0; overflow: hidden; } canvas { width: 100%; height: 100%; } </style> </head> <body> <script src="https://cdn.jsdelivr.net/npm/three@0.131.2/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.131.2/examples/js/loaders/MTLLoader.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.131.2/examples/js/loaders/OBJLoader.js"></script> <script> // 创建场景、相机、光源等 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 5); var light = new THREE.PointLight(0xffffff, 1, 100); light.position.set(0, 1, 5); scene.add(light); // 加载模型 var mtlLoader = new THREE.MTLLoader(); mtlLoader.load('s/file.mtl', function(materials) { materials.preload(); var objLoader = new THREE.OBJLoader(); objLoader.setMaterials(materials); objLoader.load('s/file.obj', function(object) { // 加载完成后,设置材质、纹理等 object.traverse(function(child) { if (child instanceof THREE.Mesh) { // child.material.map = new THREE.TextureLoader().load('s/texture.jpg'); child.material.needsUpdate = true; } }); // 加入到场景中 scene.add(object); }); }); // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 渲染场景 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); </script> </body> </html>
这是一个使用 Three.js 加载 Obj 和 Mtl 文件并添加纹理的示例代码。Three.js 是一个基于 WebGL 技术的 JavaScript 3D 渲染库,可以用来创建各种 3D 场景和动画效果。在这段代码中,我们首先创建了场景、相机和光源等基础元素,然后使用 MTLLoader 和 OBJLoader 分别加载了 Mtl 和 Obj 文件,并将它们组合成一个 3D 对象添加到场景中。最后,使用 WebGLRenderer 渲染器将场景渲染到 HTML 页面上。在加载完成后,还设置了材质、纹理等属性,以达到更好的视觉效果。
阅读全文