与OrbitControls一起转换HTML元素,以使它们看起来与场景中的对象一起旋转

时间:2018-12-03 17:49:55

标签: javascript three.js

我创建了Three.js场景,其中有一个地球仪(具有Earth纹理),可以使用OrbitControls对其进行旋转。

我想让标签“粘在”地球上的某个位置,即“澳大利亚”标签,固定在澳大利亚中心的经度和纬度上,然后在使用OrbitControls时与地球对象一起移动这样,销钉始终会停留在其位置上方。

由于各种原因(内容管理更容易,样式更容易...),我需要这些标签成为HTML元素(例如,而不是THREE.Sprite)。在我看来,这使事情变得更加棘手,因为Three.js对象可以轻松地一起旋转,但是HTML元素不会。

让您了解我想要的最简单的方法是看一个示例,因此下面的链接几乎完全是我希望我的地球仪如何工作。您会看到他们使用带有HTML标签的Three.js地球仪。

https://www.gsmlondon.ac.uk/global-oil-map/#1995-exporters

我仔细阅读了他们的代码,发现他们正在转换/翻译HTML元素,但是我无法弄清楚导致HTML元素始终停留在其起始位置的计算,完全超出了各自国家/地区。 / p>

我正在使用以下计算将纬度和经度坐标(来自谷歌地图)转换为X,Y,Z坐标,以便在我的three.js场景中使用,并且效果很好(例如,我可以创建一个小的{{1 }},并将其放置在生成的坐标处,它将显示在正确的位置上方

SphereGeometry

首先,我只是想让HTML元素在X轴上旋转。我想出了以下代码,但无法正常工作。

以下代码是使用function calcPosFromLatLonRad(lat, lon, radius){ let phi = (90 - (lat)) * (Math.PI / 180); let theta = ((lon) + 180) * (Math.PI / 180); let x = -((radius) * Math.sin(phi) * Math.cos(theta)); let z = ((radius) * Math.sin(phi) * Math.sin(theta)); let y = -((radius) * Math.cos(phi)); return [x, y, z]; } 的render函数内部函数的一部分。

RequestAnimationFrame

上方是地球半径(...element.style.transform = translate(${-Math.sin(camera.rotation.y) * 300}px,...)的300。

有人知道我如何实现一种影响,就像我链接到的代码中实现的那样吗?即无论场景旋转如何,销钉始终处于正确的位置。

谢谢。

1 个答案:

答案 0 :(得分:1)

Three.js的转换器可将3D转换应用于HTML元素。它称为CSS3DRenderer。您可以在操作here中看到它的示例。

使用该工具可以节省大量时间,而无需手动尝试确定每个元素的位置/旋转:

var scene = new THREE.Scene();
var sceneCSS = new THREE.Scene();

// Adding new CSS3DObjects to your scene:
var object = new THREE.CSS3DObject( HTMLElement );
sceneCSS.add(object);

var renderer = new THREE.WebGLRenderer();
var rendererCSS = new THREE.CSS3DRenderer();

var camera = new THREE.PerspectiveCamera();

onUpdate() {
    // This will render your WebGL 3D Scene
    renderer.render(scene, camera);

    // This will apply 3DTransforms to your HTML elements
    rendererCSS.render(sceneCSS, camera);
}