Javascript 使用控件拖动和单击对象
现在我有一个场景,有两个球体和一个位于(0,0,0)的点光源。球体使用控件围绕点旋转,但我无法在尝试拖动球体时使其移动。有人能快速查看我的代码吗,谢谢 编辑:是的,它们会移动,但我需要它们能够独立于三个控件进行拖动。就像下面的示例: 当选择一个球体时,我需要阻止THREE.Controls()并将该球体拖动到我想要的任何位置,而无需“旋转”场景Javascript 使用控件拖动和单击对象,javascript,webgl,three.js,Javascript,Webgl,Three.js,现在我有一个场景,有两个球体和一个位于(0,0,0)的点光源。球体使用控件围绕点旋转,但我无法在尝试拖动球体时使其移动。有人能快速查看我的代码吗,谢谢 编辑:是的,它们会移动,但我需要它们能够独立于三个控件进行拖动。就像下面的示例: 当选择一个球体时,我需要阻止THREE.Controls()并将该球体拖动到我想要的任何位置,而无需“旋转”场景 Brent您需要做的是根据是否选择了对象动态禁用控件 下面是我正在使用的控件: controls = new THREE.TrackballContr
Brent您需要做的是根据是否选择了对象动态禁用控件 下面是我正在使用的控件:
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
现在,THREE.JS中的控件对象创建鼠标事件,允许它们更改相机视图。我们想要的是在选择对象时禁用控件,否则在拖动时允许控件更改视图
为了做到这一点,我们可以声明一个作为标志的全局变量
var killControls = false;
当我们单击并投射光线时,这将设置为true,如果光线与指定对象碰撞,我们将设置为true
/** Event fired when the mouse button is pressed down */
function onDocumentMouseDown(event) {
event.preventDefault();
/** Calculate mouse position and project vector through camera and mouse3D */
mouse3D.x = mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse3D.y = mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse3D.z = 0.5;
projector.unprojectVector(mouse3D, camera);
var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());
var intersects = ray.intersectObject(maskMesh);
if (intersects.length > 0) {
SELECTED = intersects[0].object;
var intersects = ray.intersectObject(plane);
offset.copy(intersects[0].point).subSelf(plane.position);
killControls = true;
}
else if (controls.enabled == false)
controls.enabled = true;
}
/** This event handler is only fired after the mouse down event and
before the mouse up event and only when the mouse moves */
function onDocumentMouseMove(event) {
event.preventDefault();
/** Calculate mouse position and project through camera and mouse3D */
mouse3D.x = mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse3D.y = mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse3D.z = 0.5;
projector.unprojectVector(mouse3D, camera);
var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());
if (SELECTED) {
var intersects = ray.intersectObject(plane);
SELECTED.position.copy(intersects[0].point.subSelf(offset));
killControls = true;
return;
}
var intersects = ray.intersectObject(maskMesh);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
plane.position.copy(INTERSECTED.position);
}
}
else {
INTERSECTED = null;
}
}
/** Removes event listeners when the mouse button is let go */
function onDocumentMouseUp(event) {
event.preventDefault();
if (INTERSECTED) {
plane.position.copy(INTERSECTED.position);
SELECTED = null;
killControls = false;
}
}
/** Removes event listeners if the mouse runs off the renderer */
function onDocumentMouseOut(event) {
event.preventDefault();
if (INTERSECTED) {
plane.position.copy(INTERSECTED.position);
SELECTED = null;
}
}
在主动画循环中,以下条件将导致控件仅在单击时更新,并且不会与指定对象发生碰撞:
if (!killControls)
controls.update(delta);
else
controls.enabled = false;
编辑:我今天看到了这个,当这个答案被投票时,我看到了上面的最后一段代码,我决定我认为这更清楚,所以我在我的代码中改成了这个,当然下面和上面都是等价的:
if (killControls)
controls.enabled = false;
else
controls.update(delta);
我在Chrome上也能很好地工作是的,它们通过三个.Controls()旋转,但我需要对象在场景中独立移动,如图所示:太棒了!今天上课的时候我一直在胡闹这个主意。我会把这项工作,只要我回到我的电脑前超过5分钟。非常感谢,我会让你知道它是如何进行的!您的演示几乎正是我想要完成的,非常感谢。(我确实需要在Z平面上移动,但我很确定我知道如何完成。没问题,如果它有帮助,并且你能让它工作,那么接受答案,让其他人知道它工作。你应该能够修改代码,让对象很容易地在任意平面上移动。上面的链接已经失效,任何在线查看的方式,JSFIDLE?都没有帮助p也是。