【问题标题】:Static Buttons in React VRReact VR 中的静态按钮
【发布时间】:2017-11-24 23:11:48
【问题描述】:

我了解 vrButtons 的工作原理,但有人会如何创建覆盖在 vr hud 上的按钮。按钮是静态的,无论相机的方向如何,都会留在屏幕上。

【问题讨论】:

    标签: react-360


    【解决方案1】:

    我遇到了同样的问题,我使用了 DOM Overlay。我在 https://github.com/facebook/react-vr/tree/master/Examples/DomOverlaySample 示例和 Facebook 制作的网站的帮助下找到了解决方案:https://apps-1523878944298007.apps.fbsbx.com/instant-bundle/1523857704355225/1209114435855717/index.html

    更新:我借助以下代码向 index.vr.js 添加了一个带有回调的解决方案:https://github.com/facebook/react-vr/issues/418

    先编辑cient.js:

    import '../process';  //important to avoid a error for DOM
    import {VRInstance} from 'react-vr-web';
    import DashboardModule from "../DashboardModule";
    
    // Create a div where the overlay will be displayed in the DOM.
    const domDashboardContainer = document.createElement('div');
    domDashboardContainer.id = 'persistent-overlay';
    // Create an instance of the module, to be registered below.
    const domDashboardModule = new DashboardModule(domDashboardContainer);
    
    function init(bundle, parent, options) {
      const vr = new VRInstance(bundle, 'SuMDemo', parent, {
        // Show a gaze cursor.
        cursorVisibility: 'visible',
        ...options,
    
        // Register dom overlay module upon initialization.
        nativeModules: [domDashboardModule],
      });
    
       // Inject DOM overlay container to the player so that it is rendered          properly.
       vr.player._wrapper.appendChild(domDashboardContainer);
    
       // Attach the React Native Context to the Model
       domDashboardContainer._setRNContext(vr.rootView.context);    
    
      vr.render = function() {
        //executing on every render of the vr app
      };
      // Begin the animation loop
      vr.start();
      return vr;
    }
    
    window.ReactVR = {init}; 
    

    别忘了导入process.js(可以在这里找到https://github.com/facebook/react-vr/blob/master/Examples/DomOverlaySample/process.js)。这是一种避免错误的解决方法。

    DashboardModule.js 渲染 DOM 覆盖层的反应元素。这是一个例子:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {Module} from 'react-vr-web';
    
    import Dashboard from './DashboardLayout';
    
    export default class DashboardModule extends Module {
        constructor(overlayContainer) {
            super('DashboardModule');       //Name for the call in index.vr.js
            this._overlayContainer = overlayContainer;
            this._rnctx = null;     //react native context for callback
        }
    
        // This method call opens up the overlay for display.
        showDashboard(props, callBackBtn) {
            this.callBackBtn=callBackBtn;
            ReactDOM.render(
                <Dashboard
                    {...props}
                    onClickDash={()=>this.buttonClicked()}
                />,
                this._overlayContainer
            );
        }
    
        //setter for context
        _setRNContext(rnctx) {
            this._rnctx = rnctx;
        }
    
        buttonClicked() {
            console.log("Dashboard Button Clicked");
            //here invoke the Callback.In the second parameter ([]) you can pass arguments
            this._rnctx.invokeCallback(this.callBackBtn, []);
        }
    
        hideDashboard() {
            ReactDOM.unmountComponentAtNode(this._overlayContainer);
        }
    }
    

    DashboardLayout.js 可以是这样的:

    import React from 'react';
    
    const Dashboard = props => {
    
        return (
            <div style={{
                bottom: 0,
                left: 0,
                position: 'absolute',
                right: 0,
                top: 0,
                pointerEvents: 'none',    //important that the movement is possible
            }}>
                <div style={{
                    background: 'rgba(0, 0, 0, 0.7)',
                    border: '2px solid #ffffff',
                    borderRadius: '5px',
                    top: '20px',
                    display: 'inline-block',
                    height: '40px',
                    width: '40px',
                    marginLeft: 'auto',
                    padding: '4px',
                    position: 'absolute',
                    right: '18px',
                    verticalAlign: 'top',
                    opacity: '1',
                    cursor: 'pointer',
                    pointerEvents: 'auto',
                }}
                     onClick={props.onClickDash}>
                    <div style={{
                        margin: '4px',
                        width: '32px',
                        height: '32px',
                        backgroundImage: 'url(../static_assets/icons/menu.png)',
                    }}>
    
                    </div>
                </div>
            </div>
        );
    };
    
    export default Dashboard;
    

    重要的是在外部将pointerEvents 设置为none,然后在放置按钮的位置再次将其设置为auto。否则,VR 移动将不再使用鼠标。

    您可以通过 index.vr.js 中的 NativeModules(从 react-vr 导入它们)从 DashboardModule.js 调用方法。 在index.vr.js 中显示 DOM Overlay 调用:

    NativeModules.DashboardModule.showDashboard(
              {
                  someProps: 1        //here pass some props
              },
              ()=>this.callBackBtn()      //this is the callback function that should be called
          );
    

    NativeModule 的名称在DashboardModule.js 的构造函数中设置,在本例中为DashboardModule

    【讨论】:

    • 这太好了,谢谢。如何将 buttonClicked 事件传递回 index.vr.js?
    • 这个问题我还没找到解决办法。
    • 奇怪的是从 DashboardModule 我可以从 index.vr.js 访问道具,但我不能调用函数
    【解决方案2】:

    如果您决定在 VR 中为这些按钮使用凝视光标,您会在这里遇到一些挑战,但您有两个选择。

    您可以创建一个固定组件。您可以在此处使用 VRHeadModel 查看我的要点:https://gist.github.com/cidicles/b4e978d3f3e2de8b359bdc51b5fb3261

    你可以像这样使用它:

    &lt;Fixed&gt;Something You Want Fixed&lt;/Fixed&gt;

    这种方法是一种 VR 解决方案,该元素将出现在 VR 场景中,但更新之间确实有一点延迟。

    另一种方法是使用 DOM 覆盖。您可以在此处查看此示例:https://github.com/facebook/react-vr/tree/master/Examples/DomOverlaySample

    这只是传统的 DOM,所以没有延迟,请记住这里的任何元素在 VR 中都不可见。

    【讨论】:

      【解决方案3】:

      我想退后一步考虑一下。

      主要问题是,这是用于 VR 视图,还是您只是在网页上使用 3D 视图而不打算让人们进入 VR?

      当您在 VR 中创建“始终保持静止”的东西时,您所做的就是创建一个用户无法摆脱的浮动对象。在 VR 中会感觉非常非常奇怪。

      更糟糕的是,当他们四处移动头部时,浮动物体似乎会穿透其他物体,具体取决于您的精确耳机和光学器件。它将处于中性距离(焦平面)并且也会导致一些聚焦问题。这可能会引发聚散适应症问题。 (这实际上更多的是疲劳问题而不是疾病,但是 YSMV - 你的胃可能会有所不同)。

      在 3D 世界中制作 3D UI 确实是最好的选择。这很难,真的是——这是多年来整个博士学位都被授予的领域。 (尽管流行概念,VR 并不是新的)。

      对于“未回答的答案”感到抱歉……我希望这对您有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多