使用 DOMElements 的三个.js SphereGeometry 全景热点

Posted

技术标签:

【中文标题】使用 DOMElements 的三个.js SphereGeometry 全景热点【英文标题】:THREE.js SphereGeometry Panorama hotspots using DOMElements 【发布时间】:2015-10-26 11:29:33 【问题描述】:

我使用SphereGeometryPerspectiveCameraCanvasTexture 创建了一个简单的WebGL 3D 全景应用程序。现在,我希望通过在SphereGeometry 的某些部分添加“热点”来使场景栩栩如生。我遇到的问题是了解如何更新各种DOMElements,以便它们的位置反映更新后的Camera 位置。

基本上,随着Camera 的旋转,各种DOMElements 会相对于相机旋转的方向进出视野。我尝试使用返回的PerspectiveCamera camera.rotation<div> absolute 定位到<canvas>translating XY 位置,但它并没有真正起作用;这是我的 JS 和 CSS 实现:

CSS

#TestHotSpot 
    /* not sure if using margins is the best method to position hotspot */
    margin-top: 50px;
    margin-left: 50px;
    width: 50px;
    height: 50px;
    background: red;
    position: absolute;

JavaScript

/** 
   CONFIG is my stored object variable; it contains the PerspectiveCamera instance 
   code is being called inside of my RequestAnimationFrame
**/

config.camera.updateProjectionMatrix();
config.controls.update(delta);

document.getElementById("TestHotSpot").style.transform = "translate("+ config.camera.rotation.x +"px, "+ config.camera.rotation.y +"px)";

Here 也是所需效果的一个活生生的例子。

解决此问题的最佳解决方案是什么?当我运行它时我注意到DOMElements 只会轻微移动;我还注意到他们并没有真正考虑到它们被放置在SphereGeometry 的哪个位置(例如,被定位在Camera 的“后面”;真的很复杂!

我很乐意为THREE.js 引擎使用任何插件,并遵循任何教程。非常感谢您提前回复!

【问题讨论】:

【参考方案1】:
    尝试将平面网格/网格设置到所需的点。 复制 css 元素(使用 three.js cssObject [如果您已经知道的话] 创建的 domElements)的位置以及 planemesh/mesh 的位置。

你就完了!!

【讨论】:

嗨@serious_s,非常感谢您的回复!我试图找到一些关于如何使用cssObject 的文档,但结果却空手而归。你有解释如何使用它的代码 sn-p 示例吗?我还是有点困惑——抱歉! 您好!在做了更多的研究之后,我现在明白你的答案了——谢谢你的帮助!赞成。 如果你不介意,请分享你的研究,你做了什么 tuts 或阅读,你还发现了什么,你有一些好的链接也许也能让我理解这一点整个过程。感谢您提供任何可能被要求分享的相关信息。 嗨@lindsay 感谢您的支持。我没有注意到您的评论,因为我仍然是 *** 中的菜鸟【参考方案2】:

好的,插话我自己的问题!我遇到了一些问题,但我已经想出了如何让 CSS3d 与 THREE.js WebGL 场景混合。

所以我要做的第一件事就是更新我的 THREE.js 库;我从之前的下载中运行 71,但我需要将其更新到 Mr.Doob 在 this 示例中使用的库。我还将我的 CSS3d 库更新为同一个示例中包含的文件。

然后我用这个方法(在链接中指定的相同)创建了一个演示场景。

var camera, scene, renderer;

var scene2, renderer2;

var controls;

init();
animate();

function init() 

    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.set( 200, 200, 200 );

    controls = new THREE.TrackballControls( camera );

    scene = new THREE.Scene();
    scene2 = new THREE.Scene();

    var material = new THREE.MeshBasicMaterial(  color: 0x000000, wireframe: true, wireframeLinewidth: 1, side: THREE.DoubleSide  );

            //

    for ( var i = 0; i < 10; i ++ ) 

        var element = document.createElement( 'div' );
            element.style.width = '100px';
            element.style.height = '100px';
            element.style.opacity = 0.5;
            element.style.background = new THREE.Color( Math.random() * 0xffffff ).getStyle();

        var object = new THREE.CSS3DObject( element );
            object.position.x = Math.random() * 200 - 100;
            object.position.y = Math.random() * 200 - 100;
            object.position.z = Math.random() * 200 - 100;
            object.rotation.x = Math.random();
            object.rotation.y = Math.random();
            object.rotation.z = Math.random();
            object.scale.x = Math.random() + 0.5;
            object.scale.y = Math.random() + 0.5;
        scene2.add( object );

        var geometry = new THREE.PlaneGeometry( 100, 100 );
        var mesh = new THREE.Mesh( geometry, material );
            mesh.position.copy( object.position );
            mesh.rotation.copy( object.rotation );
            mesh.scale.copy( object.scale );
        scene.add( mesh );

    

            //

    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor( 0xf0f0f0 );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    renderer2 = new THREE.CSS3DRenderer();
    renderer2.setSize( window.innerWidth, window.innerHeight );
    renderer2.domElement.style.position = 'absolute';
    renderer2.domElement.style.top = 0;
    document.body.appendChild( renderer2.domElement );



function animate() 

    requestAnimationFrame( animate );

    controls.update();

    renderer.render( scene, camera );
    renderer2.render( scene2, camera );


在完成该工作后,我将 CSS3d sceneCSS3d objectCSS3d renderer 重新用于我的场景中。

祝其他人好运,希望这会有所帮助!

【讨论】:

我也在尝试添加带有指向其他全景图的链接的热点。你介意分享更多你是如何做到这一点的吗?也许你可以做一个jsfiddle吗?我是 ThreeJS 的残酷初学者并发布了这个 ***.com/questions/35148586/… 并且仍在寻找好的示例或教程来帮助我更好地理解整个问题。我会永远很高兴自己理解和编码。如果你能被要求做一个快速的 jsfiddle 那就太棒了! 2021 - 这仍然有助于让可点击元素覆盖我的SphereGeometry,因此该元素与全景图的其余部分一起平移。只需进行一些调整:import CSS3DRenderer, CSS3DObject from './assets/js/CSS3DRenderer.js';renderer2 = new CSS3DRenderer();

以上是关于使用 DOMElements 的三个.js SphereGeometry 全景热点的主要内容,如果未能解决你的问题,请参考以下文章

如何在 x86 中编译 sph_convert.exe

使用 UART 检查从 SPH0645 麦克风 I2S 协议接收的数据

SPH液面重构过程中的问题

sphinx SPH_MATCH_EXTENDED2 基本应用

Zombie.js 无法访问 DOM 元素的数据集属性

特效模拟:SPH流体模拟及液面重构问题