gpt4 book ai didi

three.js - 如何在三个js坐标系中正确定位html元素?

转载 作者:行者123 更新时间:2023-12-01 12:08:20 25 4
gpt4 key购买 nike

我希望有一个我无法得到答案的简单问题。

我有三个在盒子里移动的 js 几何球体。我把这个盒子放在场景的中心。球体如何留在盒子中的机制无关紧要。重要的是球体围绕原点 (0,0) 移动并且 Canvas 始终填满页面。

我想从移动的球体到页面上的 div 或 img 元素画一条线。为此,我假设我必须将 css 坐标转换为三个 js 坐标。 I found something I thought did something like this (Note: Over use of somethings to signify I am probably mistaken)

我可以将 html 元素添加到与 webgl 渲染器相同的场景/相机,但显然使用不同的渲染器,但我不确定如何从那里继续?

基本上我想知道:

  • 如果需要,我应该如何更改保持纵横比的 div 的大小?
    • 本质上,我希望 div 或元素以某个相机深度填满屏幕。
  • 如何默认将div放置在场景的中心?
    • 地雷似乎在 z 方向上移动了 1000,但这可能是我必须看到的 div(img) 的大小。
  • 如何在 webgl 球体和 html div/img 之间画一条线?

提前致谢!

最佳答案

很遗憾,您问了 3 个问题,一次解决所有问题很棘手。

我将解释如何将 DIV 元素放置在某些 3D 对象的顶部。我的示例是当您将鼠标悬停在对象上时出现的工具提示:http://jsfiddle.net/mmalex/ycnh0wze/

HTML tooltip on three.js objects

那么让我们开始吧

首先,您需要订阅鼠标事件并将鼠标的二维坐标转换为视口(viewport)上的相对坐标。解释得很好你会在这里找到它:Get mouse clicked point's 3D coordinate in three.js

具有 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);

最后看到最重要的部分,DIV 元素放置。要理解代码,必须方便地使用 Vector3.project方法。

计算顺序如下:

  1. 获取二维鼠标坐标,
  2. Raycast 对象并记住交点的 3D 坐标(如果有的话),
  3. 将 3D 坐标投影回 2D(此步骤在这里似乎是多余的,但如果您想以编程方式触发对象工具提示怎么办?您不会有鼠标坐标)
  4. 乱七八糟地将 DIV 置于 2D 点上方的中心位置,并留有良好的边距。
// 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
});
}
}

关于three.js - 如何在三个js坐标系中正确定位html元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54410532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com