facebookarchive / react-360

Create amazing 360 and VR content using React
https://facebook.github.io/react-360
Other
8.73k stars 1.23k forks source link

[Feature Request] Embedding React VR Canvas inside a normal website #234

Open billykwok opened 7 years ago

billykwok commented 7 years ago

Feature Request

Description

Currently, React VR is using the React Native approach to architect the application. However, this makes it impossible to embed React VR scene into a normal website. This usage is actually quite common since VR may sometimes just be a part of a 2D webpage. A-frame has such capability with the "embed" attribute in its scene component. This is also the reason why I pick A-frame over React VR for typical websites that require VR functionality.

Expected behavior

React VR projects should be able to be built with Webpack and other standard Javascript tools, instead of React VR CLI. Instead of having React Native-style AppRegistry.registerComponent(), the React VR canvas can be placed inside normal DOM and mounted using ReactDOM.render().

Actual behavior

React VR can only be built with React VR CLI. The VR canvas occupies the entire page and we have no way to integrate it with normal web page components.

Solution

Perhaps re-architect the project so that it can be compiled using Webpack?

andrewimm commented 7 years ago

There's actually nothing that prevents you from embedding React VR into a 2d web page today.

As noted in the documentation, the recommended way to do this is with an iframe: https://facebook.github.io/react-vr/docs/publishing.html#integrating-with-an-existing-web-page If you plan on supporting users with WebVR browsers, you also need to add the allowvr attribute to your iframe:

<iframe allowvr src="path/to/index.html" width="600" height="400" />

I personally recommend this method because you don't need to worry about ordering scripts to avoid interfering with loading other resources on the page, and it works regardless of your regular 2d application's architecture. I also feel that an iframe is ideal for embedding because it still maintains a standalone web page that you can link users to directly in cases where you do want the full page takeover (say, on mobile). Flexibility is key. When the user is actually in VR, it's best for them to be viewing a standalone web page, because in the case of a canvas embedded in a bigger web page, the web browser is still running all of the JS from the parent page, even if it's not being drawn to a screen. This could hurt performance.

If you feel the need to integrate the canvas into your main page, though, the process is fairly straightforward as well: the ReactVR.init() call that acts as the entry point of your application in html takes a parent as the second option. This defaults to document.body, but you can make it any Element or element id string. React VR will find that element and mount the canvas inside of it.

timoxley commented 7 years ago

@andrewimm an iframe kinda sidesteps the issue though. Ideally, ReactVR wouldn't require special treatment and could be loaded and bundled like any other react library, without imposing yet another bundling tool onto its users.

Going through an iframe or using the react-native packager requires bundling and serving any shared libraries (e.g. react) twice, and requires more effort to achieve interaction or code-sharing between the container app and the VR content, in addition to pain of integrating yet another bundler into your existing workflow.

Much of the benefit of being able to build VR content on top of a defacto industry standard tool, React, is defeated by having to also build on top of an incompatible, non-standard bundler. Not to mention the bundler exists primarily to enable building of cross-platform apps… but can't actually be used to do so for ReactVR content… so users are forced to pay the overheads of incompatibility for benefits they can't (yet?) reap.

billykwok commented 7 years ago

Agree. Bundling React VR and React with Webpack separately would also create redundant code.

snoblenet commented 7 years ago

@andrewimm Are you saying we actually need to deploy two apps?

I write as someone who has been using React for a while to build websites but who is now looking at React VR for the first time in order to add some VR to a website.

My first read of the React VR docs leads me to believe React VR is not designed to publish HTML at all, which would rule out using it to publish the HTML page with the iframe that encloses the VR.

I need a need a HTML page around my VR so I can preview the VR with limited controls for users who are not yet signed up and logged in.

andrewimm commented 7 years ago

@snoblenet That's correct. Don't think of React VR as JS that integrates into part of a larger web page. It's a standalone app that is best experienced through an iframe, so that you can send users of VR browsers direct to that experience. React VR is built with React Native, and that's the best comparison. A React Native app has a JS component compiled by the RN Packager, but the native portion of the app still needs to be compiled by its own toolchain (javac, xcode, etc). The two things are entirely separate, but you can embed the JS into an already large native app. It's just that in this particular case, the "native" chunk is also JS.

For now, the best answer I have for those who really want to have a single JS bundle (again, not recommended, if only for perf reasons), is to have a webpack plugin that runs the RN packager as a pre-build step. Then you can have your code require() the compiled JS and initialize your code with a call to ReactVR.init(), just as in the index.html file

In the future we will explore building with a single toolkit, whether that's extending the metro bundler to work with traditional React websites, or getting support into Webpack, but for now it's definitely not a priority of the team. However, this is open source software, so anyone who wants to explore this avenue is more than welcome to contribute.

snoblenet commented 7 years ago

OK. I'm coming around to this view. For non-users, I'm thinking of just putting a movie in my web page that demos the VR app. And for logged in users, I'm thinking of finding a way to put static non-panning controls into the VR app so I don't have to use an iFrame to give them ready access to the things I want to always keep in view. Just gotta work that out plus how to share authentication/authorisation/etc state between the web and VR apps.

ctoLarsson commented 7 years ago

snoblenet,

I struggled with the same issue. This is how I solved it, if it can be of help:

  1. To share info from the calling page to the React VR app: Send in props using initialProps
        let myinfo=123;
        ReactVR.init(
          './index.bundle.js?platform=vr',
          document.body,
          {
            initialProps: {
              myinfo: myinfo,
            }
          }
        );
  1. To get stuff out, you can add this to the end of your client.js init function:
    window.vr = vr;
    vr.rootView.context.worker.addEventListener('message', onVRMessage);

And then send out messages from the React VR environment. For example, I use it to signal finished loading the first media assets for example to remove a loading indicator from the calling page. You can see how I send out the messages in the code: https://github.com/livetourlab/live-tour-lab

Good luck!

// Anders

snoblenet commented 7 years ago

thx @anders -- cloning your repo now

snoblenet commented 7 years ago

I still have the issue that, in addition to publishing VR to /vr using React-VR, I want to publish a HTML welcome page (and other content) to index.html using ordinary React, ideally using the same code base. But given the differences between Webpack and React Native packager, that might involve me messing with innards that create-react-app and React VR CLI otherwise just magic away. Is there a demo somewhere or a React VR website with a HTML landing page, or a create-react-plus-react-vr-app like tool? Sorry I've been reading for days and I have so far found nothing. Surely I'm not the only one who wants to do this?

INIW1112SA commented 6 years ago

I have a created react website, and an react VR website. I wanted to integrate the VR application in my react website . can anyone suggest the best way to do @snoblenet i too have same requirement