【问题标题】:THREE.js SphereGeometry Panorama hotspots using DOMElements使用 DOMElements 的三个.js SphereGeometry 全景热点
【发布时间】: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 引擎使用任何插件,并遵循任何教程。非常感谢您提前回复!

【问题讨论】:

    标签: javascript css three.js


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

    你就完了!!

    【讨论】:

    • 嗨@serious_s,非常感谢您的回复!我试图找到一些关于如何使用cssObject 的文档,但结果却空手而归。你有解释如何使用它的代码 sn-p 示例吗?我还是有点困惑——抱歉!
    • 您好!在做了更多的研究之后,我现在明白你的答案了——谢谢你的帮助!赞成。
    • 如果你不介意,请分享你的研究,你做了什么 tuts 或阅读,你还发现了什么,你有一些好的链接也许也能让我理解这一点整个过程。感谢您提供任何可能被要求分享的相关信息。
    • 嗨@lindsay 感谢您的支持。我没有注意到您的评论,因为我仍然是 stackoverflow 中的菜鸟
    【解决方案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 的残酷初学者并发布了这个 stackoverflow.com/questions/35148586/… 并且仍在寻找好的示例或教程来帮助我更好地理解整个问题。我会永远很高兴自己理解和编码。如果你能被要求做一个快速的 jsfiddle 那就太棒了!
    • 2021 - 这仍然有助于让可点击元素覆盖我的SphereGeometry,因此该元素与全景图的其余部分一起平移。只需进行一些调整:import { CSS3DRenderer, CSS3DObject } from './assets/js/CSS3DRenderer.js';renderer2 = new CSS3DRenderer();
    猜你喜欢
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2017-09-26
    • 2018-04-30
    • 1970-01-01
    • 2014-08-06
    • 2015-07-05
    相关资源
    最近更新 更多