我希望有一个我无法回答的简单问题。
我有三个 js 几何球体,它们在一个盒子里移动。我把这个盒子放在场景的中心。球体如何留在盒子中的机制无关紧要。重要的是球体围绕原点 (0,0) 移动,并且画布始终充满页面。
我想从移动球体到页面上的 div 或 img 元素绘制一条线。为此,我假设我必须将 css 坐标转换为三个 js 坐标。我发现了一些我认为做了这样的事情(注意:过度使用某些东西来表示我可能弄错了)
我可以将 html 元素添加到与 webgl 渲染器相同的场景/相机,但显然使用不同的渲染器,但我不确定如何从那里继续?
基本上我想知道:
提前致谢!
不幸的是,您问了 3 个问题,一次解决它们很棘手。
我将解释如何将 DIV 元素定位在某些 3D 对象的顶部。我的例子是当你用鼠标悬停对象时出现的工具提示:http : //jsfiddle.net/mmalex/ycnh0wze/
那么让我们开始吧,
首先,您需要订阅鼠标事件并将鼠标的二维坐标转换为视口上的相对坐标。很好的解释你会在这里找到它:在three.js中获取鼠标点击点的3D坐标
具有 2D 坐标,对对象进行光线投射。这些步骤非常简单,但为了完整起见,我提供了代码块。
var raycaster = new THREE.Raycaster();
function handleManipulationUpdate() {
// cleanup previous results, mouse moved and they're obsolete now
latestMouseIntersection = undefined;
hoveredObj = undefined;
raycaster.setFromCamera(mouse, camera);
{
var intersects = raycaster.intersectObjects(tooltipEnabledObjects);
if (intersects.length > 0) {
// keep point in 3D for next steps
latestMouseIntersection = intersects[0].point;
// remember what object was hovered, as we will need to extract tooltip text from it
hoveredObj = intersects[0].object;
}
}
... // do anything else
//with some conditions it may show or hide tooltip
showTooltip();
}
// Following two functions will convert mouse coordinates
// from screen to three.js system (where [0,0] is in the middle of the screen)
function updateMouseCoords(event, coordsObj) {
coordsObj.x = ((event.clientX - renderer.domElement.offsetLeft + 0.5) / window.innerWidth) * 2 - 1;
coordsObj.y = -((event.clientY - renderer.domElement.offsetTop + 0.5) / window.innerHeight) * 2 + 1;
}
function onMouseMove(event) {
updateMouseCoords(event, mouse);
handleManipulationUpdate();
}
window.addEventListener('mousemove', onMouseMove, false);
Run Code Online (Sandbox Code Playgroud)
最后看到最重要的部分,DIV 元素放置。要理解代码,必须使用Vector3.project方便方法。
计算顺序如下:
// This will move tooltip to the current mouse position and show it by timer.
function showTooltip() {
var divElement = $("#tooltip");
//element found and mouse hovers some object?
if (divElement && latestMouseIntersection) {
//hide until tooltip is ready (prevents some visual artifacts)
divElement.css({
display: "block",
opacity: 0.0
});
//!!! === IMPORTANT ===
// DIV element is positioned here
var canvasHalfWidth = renderer.domElement.offsetWidth / 2;
var canvasHalfHeight = renderer.domElement.offsetHeight / 2;
var tooltipPosition = latestMouseProjection.clone().project(camera);
tooltipPosition.x = (tooltipPosition.x * canvasHalfWidth) + canvasHalfWidth + renderer.domElement.offsetLeft;
tooltipPosition.y = -(tooltipPosition.y * canvasHalfHeight) + canvasHalfHeight + renderer.domElement.offsetTop;
var tootipWidth = divElement[0].offsetWidth;
var tootipHeight = divElement[0].offsetHeight;
divElement.css({
left: `${tooltipPosition.x - tootipWidth/2}px`,
top: `${tooltipPosition.y - tootipHeight - 5}px`
});
//get text from hovered object (we store it in .userData)
divElement.text(hoveredObj.userData.tooltipText);
divElement.css({
opacity: 1.0
});
}
}
Run Code Online (Sandbox Code Playgroud)