Git Product home page Git Product logo

webvr-polyfill's Introduction

WebVR Polyfill

Build Status Build Status

A JavaScript implementation of the WebVR spec. This project ensures your WebVR content works on any platform, whether or not the browser/device has native WebVR support, or when there are inconsistencies in implementation.

Take a look at basic WebVR samples that use this polyfill.

Installing

Script

Download the build at build/webvr-polyfill.js and include it as a script tag, or use a CDN. You can also use the minified file in the same location as webvr-polyfill.min.js.

  <script src='webvr-polyfill.js'></script>
  <!-- or use a link to a CDN -->
  <script src='https://cdn.jsdelivr.net/npm/webvr-polyfill@latest/build/webvr-polyfill.js'></script>

npm

If you're using a build tool like browserify or webpack, install it via npm.

$ npm install --save webvr-polyfill

Using

Instructions for using versions >=0.10.0. For <=0.9.x versions, see 0.9.40 tag.

The webvr-polyfill exposes a single constructor, WebVRPolyfill that takes an object for configuration. See full configuration options at src/config.js.

Be sure to instantiate the polyfill before calling any of your VR code! The polyfill needs to patch the API if it does not exist so your content code can assume that the WebVR API will just work.

If using script tags, a WebVRPolyfill global constructor will exist.

var polyfill = new WebVRPolyfill();

In a modular ES6 world, import and instantiate the constructor similarly.

import WebVRPolyfill from 'webvr-polyfill';
const polyfill = new WebVRPolyfill();

Here's an example of querying displays and setting up controls based on environment. Remember, you'll still need to provide controls and code to support a desktop-like experience if no native VRDisplays are found, as the CardboardVRDisplay is only on mobile. See the example.

// Polyfill always provides us with `navigator.getVRDisplays`
navigator.getVRDisplays().then(displays => {
  // If we have a native VRDisplay, or if the polyfill
  // provided us with a CardboardVRDisplay, use it
  if (displays.length) {
    vrDisplay = displays[0];
    controls = new THREE.VRControls(camera);
    vrDisplay.requestAnimationFrame(animate);
  } else {
    // If we don't have a VRDisplay, we're probably on
    // a desktop environment, so set up desktop-oriented controls
    controls = new THREE.OrbitControls(camera);
    requestAnimationFrame(animate);
  }
});

iframes

There are some concerns and caveats when embedding polyfilled WebVR content inside iframes. More information is documented in the cardboard-vr-display README.

Goals

The polyfill's goal is to provide a library so that developers can create content targeting the WebVR API without worrying about what browsers and devices their users have in a world of growing, but fragmented support.

The three main components of the polyfill are:

  • Injects a WebVR 1.1 JavaScript implementation if one does not exist
  • Patches browsers that have an incomplete or inconsistent implementation of the API
  • Provide a synthesized CardboardVRDisplay on mobile when WebVR is not supported, or if it does have native support but no native VRDisplays and PROVIDE_MOBILE_VRDISPLAY is true (default).

Performance

Performance is critical for VR. If you find your application is too sluggish, consider tweaking some of the above parameters. In particular, keeping BUFFER_SCALE at 0.5 (the default) will likely help a lot.

Developing

If you're interested in developing and contributing on the polyfill itself, you'll need to have npm installed and familiarize yourself with some commands below. For full list of commands available, see package.json scripts.

$ git clone [email protected]:immersive-web/webvr-polyfill.git
$ cd webvr-polyfill/

# Install dependencies
$ npm install

# Build uncompressed JS file
$ npm run build

# Run tests
$ npm test

# Watch src/* directory and auto-rebuild on changes
$ npm watch

Testing

Right now there are some unit tests in the configuration and logic for how things get polyfilled. Be sure to run tests before submitting any PRs, and bonus points for having new tests!

$ npm test

Due to the nature of the polyfill, be also sure to test the examples with your changes where appropriate.

Releasing a new version

For maintainers only, to cut a new release for npm, use the [npm version] command. The preversion, version and postversion npm scripts will run tests, build, add built files and tag to git, push to github, and publish the new npm version.

npm version <semverstring>

License

This program is free software for both commercial and non-commercial use, distributed under the Apache 2.0 License.

webvr-polyfill's People

Contributors

aykelith avatar borismus avatar brandonocasey avatar brianchirls avatar caseyyee avatar cvan avatar deathcap avatar dmarcos avatar gkatsev avatar gordonbrander avatar halfdanj avatar himorin avatar huningxin avatar jeromeetienne avatar johnmaf avatar joshmarinacci avatar jsantell avatar jzitelli avatar machenmusik avatar marciot avatar mattiasbuelens avatar ngokevin avatar roboshoes avatar santanm avatar stuartpb avatar tbalouet avatar thelarkinn avatar thoragio avatar toji avatar trakout avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webvr-polyfill's Issues

Touch causes URL bar to become visible in iOS

iOS doesn't support proper fullscreen and instead scrolls the page down so the URL bar is no longer visible. Touching to rotate the VR view also causes the page to scroll making the URL bar visible again.

I think the solution to this is to cancel the event in the touchstart listener callback.

Disclaimer: I have only tested this on the iOS simulator, since I don't have an actual iPhone.

Use npm modules instead of bundling three-math.js

z-axis up

I'm having trouble figuring out how to get camera movement to behave correctly in a scene where the z axis is the vertical axis. When the scene loads, the camera is pointing down the z axis, which in my scene the floor. Can anyone point me and my camera in the right direction?

Fix UI in iOS

Some UI glitches in iOS.

  • White background (around the eyes) should be black in VR mode
  • Back button should be black, and much smaller
  • Back button should work

img_1180

cc: @toji

Version update needed

The latest commit f5366c8 has breaking changes, which webvr-boilerplate is depending on, but did not update the version. Please update bower.json and package.json so the latest version gets pulled by the respective package manager. Thanks.

Mobile has trouble with "forward" in landscape mode

When viewing the boilerplate demo on both iOS and Android devices, the rotating cube appears in front of me when holding the device in portrait mode.

When in landscape mode, the cube appears either 90 degrees to my left or right depending on whether I'm in landscape left or landscape right.

This happens even when I manually call for a resetPose. It seems that device orientation needs to be accounted for in the pose reset.

Add anaglyph mode

Please add anaglyph view mode (for users who have no VR headset).

Suggestion/Question: normalize the accelerometer and gyroscope data on mobile devices

Firstly, I have to say thank you for the awesome and useful repository. It has made learning VR in the browser approachable.

I have been developing a display reticle manger to help with gaze interactions and found that when testing on different phones e.g. iOS and Android the initial load position differs, even on the same device at different orientations (i.e. iPhone 6 holding it in landscape and portrait will generate different results).

Have you considered normalizing the accelerometer and gyroscope data before sending it back to VRControls.js? For example using a similar approach as gyronorm.js you could update the alpha, beta and gamma values in getOrientation method allowing for most mobile devices to have a similar result...

Below is very rough example of what I mean.

GyroPositionSensorVRDevice.prototype.getOrientation = function(data) {
  if (this.deviceOrientation == null) {
    return null;
  }

  // Rotation around the z-axis.
  //var alpha = THREE.Math.degToRad(this.deviceOrientation.alpha);
  var alpha = THREE.Math.degToRad(data.do.alpha);
  //console.log(alpha, data.do.alpha)
  // Front-to-back (in portrait) rotation (x-axis).
  //var beta = THREE.Math.degToRad(this.deviceOrientation.beta);
  var beta = THREE.Math.degToRad(data.do.beta);
  // Left to right (in portrait) rotation (y-axis).
  //var gamma = THREE.Math.degToRad(this.deviceOrientation.gamma);
  var gamma = THREE.Math.degToRad(data.do.gamma);

support Oculus

This is probably a stupid question but I could not find straight forward information on the relation between Oculus and webvr-polyfill.

Is the Oculus supported on regular FF (without vr enable) and Chrome (standard) ?

To me it looks like the Oculus is not supported, only mobile. Perhaps it is not even possible to support the Oculus currently since the the necessary browser support would only benefit a tiny percentage of users and is therefore only made available in special browsers ?

But if you need special browsers for Oculus support why then use the polyfill in the first place ? I am sure I am missing something.

Is the polyfill targeted at mobile (cardbox, Gear) only ?

Apologies for the confusion but I would be very thankful for any clarification.

Export `WebVRPolyfill` as standalone module

In main.js, instead of calling new WebVRPolyfill(); or window.InitializeWebVRPolyfill (which calls new WebVRPolyfill(); at some later time), window.WebVRPolyfill should be exposed for browsers and for CommonJS module.exports = WebVRPolyfill.

This allows folks to use window.WebVRPolyfill or require('webvr-polyfill') in browsers and CommonJS, respectively.

And browserify will handle the conditional UMD (window, CommonJS, AMD) exporting for you. Just need to change src/main.js and have browserify export a standalone bundle.

Allow Cardboard UI to be disabled

It'd be nice if there was a pref on WebVRConfig to not create the Cardboard UI (the back arrow, centerline, gear icon for settings).

Dynamically enabling/disabling the polyfill

Hey there!

Is there a way to dynamically enable or disable the polyfill?

I don't like the polyfill to be active as soon as the script gets added to the HTML page.

For example, it immediately starts overwriting my controls when in mobile mode.
I would like to keep a regular multitouch experience when the user navigates the scene and only switch to VR mode when the user presses a button.

Did I miss something here?

How can I accomplish this with the polyfill?

Thanks,
Sandro

mouse-controls are attached to the window, behaviour should be configurable

mouse-controls are attached to the window, behaviour should be configurable

https://github.com/borismus/webvr-polyfill/blob/master/src/mouse-keyboard-position-sensor-vr-device.js#L37-L40

When custom video controls such as a seek bar are created, mouse events from those bubble to the window causing unwanted camera movement. The element used here should be configurable and/or the methods bound to the window should be configurable.

As a work-around I've modified a local copy of this file with the following,

MouseKeyboardPositionSensorVRDevice.prototype.onMouseDown_ = function(e) {
  var elem = (function (e) {
    var fn = function () {};
    if (typeof e === 'object' && e) {
      if ('target' in e) {
        fn = function (ev) {
          return ev.target;
        };
      } else if ('srcElement' in e) {
        fn = function (ev) {
          return ev.srcElement;
        };
      }
    }
    return fn(e);
  }(e));

  if (/canvas/i.test(elem.tagName)) {
    this.rotateStart.set(e.clientX, e.clientY);
    this.isDragging = true;
  }
};

Samsung Gear VR as a cardboard viewer

While access to the samsung gear vr is limited through the Oculus platform, it is easy to disable the oculus platform autolaunch (which usually triggers when the smartphone is plugged to the gear vr).
It would therefore be nice to have a compatible cardboard viewer in polyfill to enable correct rendering.

Set correct canvas CSS size when presenting VR

The latest VREffect bundled with three.js (r76+) sets the appropriate canvas size when it receives a vrdisplaypresentchange event, but since it does not change the CSS height and width, it is the wrong size. The height is often too small, because it was previously set to innerHeight, which leaves room for the URL bar.

It is not VREffect's responsibility to change this, since it assumes it's just submitting frames to the VRDisplay, not rendering to the DOM. And now that the polyfill has a wrapper around the canvas that serves as the full screen element, there's extra space left in the wrapper element. I presume it would be the same with other frameworks.

I'd make a pull request, but I'm not sure of the best way to do this. One option is to set the element's inline style dimensions to the full window in VR and then set it back again when exiting presentation. But that can be difficult to get right every time, especially if the canvas is displayed inline and/or doesn't take up the full window. Another option is to use a CSS rule with !important for height and width in the special case of VR presentation, but that feels...icky.

Any ideas?

Head-neck model for positional data

Prior to gaining positional support with the DK2 the DK1 and now the Gear VR generate approximate positional data from HMD rotation and a head-neck model that perhaps subtly but still significantly makes for a better experience. What are your thoughts on implementing somethings similar as part of GyroPositionSensorVRDevice?

Remove src from .npmignore

Would it be possible to add the source files back into the npm package? I found it very useful for making minor customizations.

I don't think there's much down side to including these files, since they're not very big and would not affect what's delivered to the browser for people who want to use the built file. This would not include node_modules.

Thanks

webvr-polyfill raises strict SyntaxError when concatenated or minified with other files

Got this on 0.9.2 with firefox stable (45) but certainly the same on other versions as well

SyntaxError: in strict mode code, functions may be declared only at top level or immediately within another function

VRDisplay.prototype.requestPresent = function(layer) {
  var self = this;
  this.layer_ = layer;

  return new Promise(function(resolve, reject) {
    if (!self.capabilities.canPresent) {
      reject(new Error('VRDisplay is not capable of presenting.'));
      return;
    }

    self.waitingForPresent_ = false;
    if (layer && layer.source) {
      var fullscreenElement = self.wrapForFullscreen(layer.source);

function onFullscreenChange() {

        var actualFullscreenElement = Util.getFullscreenElement();

        self.isPresenting = (fullscreenElement === actualFullscreenElement);

Make WebVRConfig options consistent

IMO, all boolean names should be changed to be truthy ones. We already have FORCE_ENABLE_VR, ENABLE_DEPRECATED_API, DEFER_INITIALIZATION, MOUSE_KEYBOARD_CONTROLS_DISABLED. Let's make the naming consistent.

Allow to provide custom HMDVRDevice default

Currently enablePolyfill assumes that it's being used with a Cardboard device on all mobile phones.
To use it with different devices (e.g. Samsung Gear) it would be nice if this could be configured.

WebVRPolyfill.prototype.enablePolyfill = function() {
  // Initialize our virtual VR devices.
  if (this.isCardboardCompatible()) {
    this.devices.push(new CardboardHMDVRDevice());
  }

How about allowing to pass a list of devices to that function? This would probably also require to make the instantiation explicit. What do you think about something along the lines of:

var webVRPolyfill = new WebVRPolyfill();
var deviceList = [new MyDevice()];
webVRPolyfill.enablePolyfill(deviceList);

In case no list is passed it could be auto detected.

BTW do you know how WebVR in Chrome will eventually detect what device is used? NFC chip?

Do not vendor `node_modules` for `src/`

I mentioned this in a couple other issues/PRs (such as #34), this one most recently for #58.

I recommend reconsidering "vendoring" the node_modules directory for the main lib code (src/).

I think committing the node_modules for the examples/ is fine mainly for these two reasons:

  1. Works (and deployable) out of the box. folks can fire up the examples/ locally (and when deployed to GitHub Pages) without needing to first run any npm scripts (assuming build/webvr-polyfill.js is up to date).
  2. Contains external dependencies that are not included in the webvr-polyfill Browserify bundle. examples/basic/index.html relies on JS files that are not included in the build/webvr-polyfill.js bundle.

For the main library code in src/, however, I think its node_modules should not be checked in. Right now, the only dependency for webvr-polyfill bundle is es6-promise, but I can see that changing soon - perhaps for a few of these modules:

Anyway, off the top of my head, these are the main reasons I could think of to stop vendoring src/'s node_modules:

  1. Forces developers to use npm2 or npm3. npm3 introduced a flat dependency-tree structure. This means whichever version of npm was used to commit the node_modules must match the user's npm version. Many folks, myself included, have switched over to npm3 (its official release was back in June 2015); and, for what it's worth, it's also the version installed by Homebrew now when a user runs brew install npm. This causes a mess of unstaged dependencies when trying to commit code:
    screenshot 2016-04-03 22 57 33
    You could upgrade to npm3 and commit the node_modules with the new npm3 directory structure. But that also means any users using npm2 will be out of luck and will be forced to upgrade to npm3.
  2. npm install is easy for contributors. since npm scripts are necessary for doing local development, I have to already npm run build and npm run watch, I think it's safe to say that developers will have no issue running npm install once after cloning the repo (and with new updates, of course).
  3. Reviewing pull requests with vendor changes are messy, noisy, and potentially unsafe. When third-party modules are added or upgraded, malicious code changes may go undetected in the large diffs. Especially on GitHub, the diffs in the PRs won't even be visible; you'd have to apply the patch locally to see the git diff. It's definitely an aside, but calculating hashes of the node_modules is really the only way to ensure what's obtained from npm is what's in node_modules. And npm shrinkwrap is the solution for that. I've used it in the past, and it's helpful especially when you want to make sure that the dependencies used in your local development environment are the exact same ones used in your production environment (mostly important for backend code of course).
  4. Requires careful, manual work to remove dependencies. Folks should always be removing dependencies with npm uninstall, but many folks don't; they instead just remove it from the package.json. In these cases, if not caught in the pull request, an unused dependency could easily linger in the vendored node_modules directory. And with npm3's flat dependency-tree structure, the dependency relationships are no longer obvious, so it's usually nearly impossible to discern which modules are still needed by looking at the node_modules. This is a solved problem if the dependencies are instead managed by the user with npm install.
  5. Lack of precedent in OSS libraries. Although I have heard of folks "vendoring" their node_modules, I actually can't find any examples of OSS Node projects that do it.

Apologies for the verbosity. It's not my intent to be pedantic; I wanted to be thorough in explaining the case against vendoring src/'s node_modules. This was actually a good exercise to think of all the pros and cons. Anyway, let me know your thoughts.

Keyboard Controls UX

I suggest we add an option to disable the keydown listener that controls camera rotation. PointerLock and click-to-drag controls make the most sense on desktop, and this allows more complex environments to use their own keyboard events for positional movement systems.

WebVRConfig.KEYBOARD_CONTROLS = false; // default true (backward compatible)
// in MouseKeyboardPositionVRDevice()
if (WebVRConfig.KEYBOARD_CONTROLS !== false) {
  window.addEventListener('keydown', this.onKeyDown_.bind(this));
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.