Статические кнопки в React VR

Я понимаю, как работают vrButtons, но как создать кнопки, которые накладываются на vr hud. Кнопки статичны и остаются на экране независимо от того, как ориентирована камера.


person nacerillo    schedule 24.11.2017    source источник


Ответы (3)


У меня была такая же проблема, и я использовал DOM Overlay. Я нашел решение с помощью https://github.com/facebook/react-vr/tree/master/Examples/DomOverlaySample и веб-сайт, созданный Facebook, здесь: https://apps-1523878944298007.apps.fbsbx.com/instant-bundle/1523857704355225/1209114435855717/index

Обновление: я добавил решение с обратным вызовом в 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 Overlay. Вот пример:

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 больше не работает с помощью мыши.

Вы можете вызывать методы из DashboardModule.js через NativeModules (импортировать их из react-vr) в index.vr.js. Чтобы показать вызов DOM Overlay в index.vr.js:

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

Имя NativeModule задается в конструкторе DashboardModule.js, в данном случае DashboardModule.

person luki    schedule 29.11.2017
comment
Это здорово, спасибо. Как передать событие buttonClicked обратно в index.vr.js? - person cal; 13.12.2017
comment
Это проблема, решения которой я пока не нашел. - person luki; 13.12.2017
comment
Как ни странно, из DashboardModule я могу получить доступ к свойствам из index.vr.js, но не могу вызывать функции. - person cal; 13.12.2017

Здесь вы столкнетесь с некоторыми проблемами, если решите использовать курсор взгляда в VR для этих кнопок, но у вас есть два варианта.

Вы можете создать фиксированный компонент. Вы можете ознакомиться с моей сутью для одного из них, используя VRHeadModel, здесь: /cidicles/b4e978d3f3e2de8b359bdc51b5fb3261

Вы можете использовать это так же, как:

<Fixed>Something You Want Fixed</Fixed>

Этот подход является решением для виртуальной реальности, и этот элемент будет присутствовать в сцене виртуальной реальности, но между обновлениями будет небольшая задержка.

Другой метод заключается в использовании наложения DOM. Вы можете посмотреть этот пример здесь: https://github.com/facebook/react-vr/tree/master/Examples/DomOverlaySample

Это просто традиционный DOM, поэтому задержки нет, просто имейте в виду, что любые элементы здесь не будут видны в виртуальной реальности.

person cidicles    schedule 27.11.2017

Я хочу сделать шаг назад и подумать об этом.

Главный вопрос: это для просмотра в виртуальной реальности или вы просто используете 3D-просмотр на веб-странице, не предполагая, что люди будут переходить в виртуальную реальность?

Когда вы создаете что-то, что в виртуальной реальности «всегда остается неподвижным», вы создаете плавающий объект, от которого пользователь не может избавиться. В VR это будет очень, очень странно.

Хуже того, когда они двигают головой, кажется, что плавающий объект проникает в другие объекты, в зависимости от вашей точной гарнитуры и оптики. Он будет находиться на нейтральном расстоянии (в фокальной плоскости) и также вызовет некоторые проблемы с фокусировкой. Это может спровоцировать болезнь вергентной аккомодации. (На самом деле это скорее проблема усталости, чем болезни, но YSMV - ваш желудок может отличаться).

Действительно лучше всего создавать 3D-интерфейс, когда вы находитесь в 3D-мире. Это сложно, это действительно так — это область, в которой на протяжении многих лет были присвоены целые докторские степени. (VR, вопреки распространенному мнению, не новинка).

Извините за «ответ без ответа» ... Надеюсь, это немного поможет.

person J. Gwinner    schedule 04.12.2017