使用鼠标 three.js 在浏览器中操作对象
Manipulate objects in the browser with three.js using the mouse
我有这段代码(见下文),我曾用 three.js
:
绘制立方体
// revolutions per second
var angularSpeed = 0.0;
var lastTime = 0;
function animate(){
// update
var time = (new Date()).getTime();
var timeDiff = time - lastTime;
var angleChange = angularSpeed * timeDiff * 2 * Math.PI / 1000;
cube.rotation.y += angleChange;
lastTime = time;
// render
renderer.render(scene, camera);
// request new frame
requestAnimationFrame(animate);
}
// renderer
var container = document.getElementById("container");
var renderer = new THREE.WebGLRenderer();
renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);
// camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 700;
// scene
var scene = new THREE.Scene();
// cube Length, Height, Width
var cube = new THREE.Mesh(new THREE.CubeGeometry(400, 200, 200), new THREE.MeshBasicMaterial({
wireframe: true,
color: '#ff0000'
}));
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
// start animation
animate();
有谁知道是否可以允许用户通过使用鼠标拖动边缘来更改立方体的大小?
在您的设置代码中为 mousemove 添加事件侦听器:
// Event Handlers
renderer.domElement.addEventListener('mousemove', onDocumentMouseMove, false);
然后在事件处理程序代码中,您可以检查选择了哪个对象并调整缩放参数。
function onDocumentMouseMove(event) {
...
var selected = raycaster.intersectObjects(objects);
if (selected.length > 0) {
// Do things to the scale parameter(s)... Just for demo purposes
selected.scale.x = selected.scale.x + selected[0].point.sub(offset).x / 1000;
selected.scale.y = selected.scale.y + selected[0].point.sub(offset).y / 1000;
return;
}
...
}
由于我这里输入的是伪代码,很容易出错,所以留了一个测试版给大家试试:http://www.numpty.co.uk/cubedrag.html
如您所见,所选对象的大小随着鼠标的拖动而发生可怕的变化。你让我感兴趣,所以如果我有更多时间,我会考虑让它与运动成比例。
检查 this jsfiddle. I reused the structure of draggableCubes,稍作改动:
- 拖动 顶点 我创建了 vertexHelpers(小球体);
- 为了避免数学,诀窍是使用一个看不见的平面将你的 objects/vertices 垂直于相机拖动。要查看实际效果,只需设置
plane.visible=true
- 现在我们可以正确地拖动一个vertexHelper,它到立方体中心的距离发生变化。我们只需要以相同的比例缩放立方体:
在 mouseMove
侦听器的函数中变为:
if(SELECTED){
var intersects=raycaster.intersectObject(plane);
//so we get the mouse 3D coordinates in intersects[0].point
var previousDistance=SELECTED.position.sub(cube.position).length();
var increaseRatio=intersects[0].point.sub(cube.position).length()/previousDistance;
cube.scale.set(
cube.scale.x*increaseRatio,
cube.scale.y*increaseRatio,
cube.scale.z*increaseRatio
);
//then update the vertexHelpers position (copy the new vertices positions)
}
编辑:
在您的问题中,您精确地要求通过拖动其 边 来调整立方体的大小。例子里没记住,也没有凭直觉去想,不过照着做也是可以的。
然而,鉴于 lineWidth
未在 ANGLE 中实现(在 windows 上用于翻译 WebGL 的程序),选择 1px 宽度的线条并不容易。我记得一个我找不到的 threejs 示例,其中几何图形与线条相关联,因此它看起来有轮廓。基本上你可以通过创建一个自定义的圆柱体来做到这一点 'edgesHelpers'(我并不是在谈论 THREE.EdgesHelper
)并且每次立方体也必须调整它们的大小。
我有这段代码(见下文),我曾用 three.js
:
// revolutions per second
var angularSpeed = 0.0;
var lastTime = 0;
function animate(){
// update
var time = (new Date()).getTime();
var timeDiff = time - lastTime;
var angleChange = angularSpeed * timeDiff * 2 * Math.PI / 1000;
cube.rotation.y += angleChange;
lastTime = time;
// render
renderer.render(scene, camera);
// request new frame
requestAnimationFrame(animate);
}
// renderer
var container = document.getElementById("container");
var renderer = new THREE.WebGLRenderer();
renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);
// camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 700;
// scene
var scene = new THREE.Scene();
// cube Length, Height, Width
var cube = new THREE.Mesh(new THREE.CubeGeometry(400, 200, 200), new THREE.MeshBasicMaterial({
wireframe: true,
color: '#ff0000'
}));
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
// start animation
animate();
有谁知道是否可以允许用户通过使用鼠标拖动边缘来更改立方体的大小?
在您的设置代码中为 mousemove 添加事件侦听器:
// Event Handlers
renderer.domElement.addEventListener('mousemove', onDocumentMouseMove, false);
然后在事件处理程序代码中,您可以检查选择了哪个对象并调整缩放参数。
function onDocumentMouseMove(event) {
...
var selected = raycaster.intersectObjects(objects);
if (selected.length > 0) {
// Do things to the scale parameter(s)... Just for demo purposes
selected.scale.x = selected.scale.x + selected[0].point.sub(offset).x / 1000;
selected.scale.y = selected.scale.y + selected[0].point.sub(offset).y / 1000;
return;
}
...
}
由于我这里输入的是伪代码,很容易出错,所以留了一个测试版给大家试试:http://www.numpty.co.uk/cubedrag.html 如您所见,所选对象的大小随着鼠标的拖动而发生可怕的变化。你让我感兴趣,所以如果我有更多时间,我会考虑让它与运动成比例。
检查 this jsfiddle. I reused the structure of draggableCubes,稍作改动:
- 拖动 顶点 我创建了 vertexHelpers(小球体);
- 为了避免数学,诀窍是使用一个看不见的平面将你的 objects/vertices 垂直于相机拖动。要查看实际效果,只需设置
plane.visible=true
- 现在我们可以正确地拖动一个vertexHelper,它到立方体中心的距离发生变化。我们只需要以相同的比例缩放立方体:
在 mouseMove
侦听器的函数中变为:
if(SELECTED){
var intersects=raycaster.intersectObject(plane);
//so we get the mouse 3D coordinates in intersects[0].point
var previousDistance=SELECTED.position.sub(cube.position).length();
var increaseRatio=intersects[0].point.sub(cube.position).length()/previousDistance;
cube.scale.set(
cube.scale.x*increaseRatio,
cube.scale.y*increaseRatio,
cube.scale.z*increaseRatio
);
//then update the vertexHelpers position (copy the new vertices positions)
}
编辑: 在您的问题中,您精确地要求通过拖动其 边 来调整立方体的大小。例子里没记住,也没有凭直觉去想,不过照着做也是可以的。
然而,鉴于 lineWidth
未在 ANGLE 中实现(在 windows 上用于翻译 WebGL 的程序),选择 1px 宽度的线条并不容易。我记得一个我找不到的 threejs 示例,其中几何图形与线条相关联,因此它看起来有轮廓。基本上你可以通过创建一个自定义的圆柱体来做到这一点 'edgesHelpers'(我并不是在谈论 THREE.EdgesHelper
)并且每次立方体也必须调整它们的大小。