我创建了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。
有人知道我如何实现一种影响,就像我链接到的代码中实现的那样吗?即无论场景旋转如何,销钉始终处于正确的位置。
谢谢。
答案 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);
}