webvr js meetup initial commit
This commit is contained in:
14
node_modules/webvr-ui/.eslintrc.json
generated
vendored
Normal file
14
node_modules/webvr-ui/.eslintrc.json
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": ["eslint:recommended", "google"],
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"rules": {
|
||||
"max-len": [2,120]
|
||||
}
|
||||
|
||||
}
|
||||
14
node_modules/webvr-ui/.npmignore
generated
vendored
Normal file
14
node_modules/webvr-ui/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# editor files
|
||||
.idea/
|
||||
*.swp
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
|
||||
node_modules
|
||||
|
||||
.DS_Store
|
||||
25
node_modules/webvr-ui/CONTRIBUTING.md
generated
vendored
Normal file
25
node_modules/webvr-ui/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# How to contribute
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are
|
||||
just a few small guidelines you need to follow.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Contributions to any Google project must be accompanied by a Contributor License
|
||||
Agreement. This is necessary because you own the copyright to your changes, even
|
||||
after your contribution becomes part of this project. So this agreement simply
|
||||
gives us permission to use and redistribute your contributions as part of the
|
||||
project. Head over to <https://cla.developers.google.com/> to see your current
|
||||
agreements on file or to sign a new one.
|
||||
|
||||
You generally only need to submit a CLA once, so if you've already submitted one
|
||||
(even if it was for a different project), you probably don't need to do it
|
||||
again.
|
||||
|
||||
## Code reviews
|
||||
|
||||
All submissions, including submissions by project members, require review. We
|
||||
use GitHub pull requests for this purpose. Consult [GitHub Help] for more
|
||||
information on using pull requests.
|
||||
|
||||
[GitHub Help]: https://help.github.com/articles/about-pull-requests/
|
||||
202
node_modules/webvr-ui/LICENSE
generated
vendored
Normal file
202
node_modules/webvr-ui/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
118
node_modules/webvr-ui/README.md
generated
vendored
Normal file
118
node_modules/webvr-ui/README.md
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
# WebVR UI
|
||||
A javascript library allowing easily to create the Enter VR button a [WebVR](https://webvr.info) site. It will automatically detect the support in the browser and show correct messages to the user. The intention for the library is to create an easy way to make a button solving as many of the common use cases of WebVR as possible, and show some best practices for how to work with WebVR.
|
||||
|
||||
The library also supports adding a *Enter Fullscreen* link that allows entering a mode where on desktop you can use the mouse to drag around, and on mobile rotate the camera based on the gyroscope without rendering in stereoscopic mode (also known as *Magic Window*)
|
||||
|
||||
### Examples
|
||||
- [Basic usage](http://googlevr.github.io/webvr-ui/examples/basic.html) Shows how to simply add a button with the default styling to a site using three.js ([source](/examples/basic.html))
|
||||
- [A-Frame usage](http://googlevr.github.io/webvr-ui/examples/aframe.html) Shows how to use the library with [A-Frame](https://aframe.io) ([source](/examples/aframe.html))
|
||||
- [Styling options](http://googlevr.github.io/webvr-ui/examples/styling.html) Shows how customize the styling through options ([source](/examples/styling.html))
|
||||
- [Custom DOM](http://googlevr.github.io/webvr-ui/examples/customDom.html) Shows how to use the library with a custom DOM for the button [A-Frame](https://aframe.io) ([source](/examples/customDom.html))
|
||||
|
||||
|
||||
## Library Usage
|
||||
### Include WebVR UI
|
||||
Get the library either by cloning or downloading it (will come to npm).
|
||||
|
||||
Include the ES5 transpiled library in a script tag
|
||||
|
||||
```html
|
||||
<script src="/webvr-ui/build/webvr-ui.min.js"></script>
|
||||
```
|
||||
|
||||
or include it in your ES2015 code
|
||||
|
||||
```javascript
|
||||
import * as webvrui from 'webvr-ui';
|
||||
```
|
||||
|
||||
The constructor for the button needs the dom element of the WebGL canvas. To use it together with the `THREE.WebGLRenderer`, do something like this
|
||||
|
||||
```javascript
|
||||
var renderer = new THREE.WebGLRenderer();
|
||||
|
||||
var options = {}
|
||||
var enterVR = new webvrui.EnterVRButton(renderer.domElement, options);
|
||||
document.body.appendChild(enterVR.domElement);
|
||||
```
|
||||
|
||||
### A-Frame
|
||||
To use the button in [A-Frame](https://aframe.io/), include the library as above, and add `webvr-ui` to the scene.
|
||||
|
||||
```html
|
||||
<a-scene webvr-ui>
|
||||
...
|
||||
</a-scene>
|
||||
```
|
||||
|
||||
This will disable the default UI and add a *Enter VR* button to the document DOM. All the styling and text options bellow are also available.
|
||||
|
||||
|
||||
### Options
|
||||
These are the supported options in `EnterVRButton`. All options are optional.
|
||||
|
||||
**Styling**
|
||||
|
||||
- `color`: Set the text and icon color *(default: `rgb(80,168,252)`)*
|
||||
- `background`: Set the background color, set to `false` for no background *(default: `false`)*
|
||||
- `corners`: Choose the corner radius. Can either be `'square'` or `'round'` or a number representing pixel radius *(default: `'square'`)*
|
||||
- `disabledOpacity`: The opacity of the button when disabled *(default: `0.5`)*
|
||||
- `domElement`: Provide a DOM element to use instead of default build in DOM. See [Custom DOM example](http://googlevr.github.io/webvr-ui/examples/customDom.html) for more details how to use.
|
||||
- `injectCSS`: Set to false to disable CSS injection of button style *(default: `true`)*
|
||||
|
||||
**Text**
|
||||
|
||||
- `textEnterVRTitle`: The text in the button prompting to begin presenting *(default: `'ENTER VR'`)*
|
||||
- `textExitVRTitle`: The text in the button prompting to begin presenting *(default: `'EXIT VR'`)*
|
||||
- `textVRNotFoundTitle`: The text in the button when there is no VR headset found *(default: `'VR NOT FOUND'`)*
|
||||
|
||||
**Function Hooks**
|
||||
|
||||
- `beforeEnter():Promise`: Function called right before entering VR. Must return a Promise. Gives the opportunity to provide custom messaging or other changes before the experience is presented.
|
||||
- `beforeExit():Promise`: Function called right before exiting VR. Must return a promise. Gives the opportunity to update UI or other changes before the presentation is exited.
|
||||
- `onRequestStateChange(state):boolean`: A function called before state is changed, use to intercept entering or exiting VR for example. Return `true` to continue with default behavior, or `false` to stop the default behavior.
|
||||
|
||||
|
||||
### Events
|
||||
The following events will be broadcasted by `EnterVRButton`
|
||||
- `ready` Event called when VR support is first detected
|
||||
- `enter` Event called when user enters VR
|
||||
- `exit` Event called when user exits VR
|
||||
- `error` Event called when an error occurs, i.e. VR is not supported
|
||||
- `hide` Event called when button is hidden
|
||||
- `show` Event called when button is shown
|
||||
|
||||
|
||||
### Functions
|
||||
These are some of the functions that can be called on the EnterVRButton
|
||||
|
||||
- `setTitle(title)` Change the text in the button.
|
||||
- `setTooltip(tooltip)` Change the hover tooltip of the button.
|
||||
- `show()` / `hide()` Change the visibility of the button.
|
||||
- `disable()` / `enable()` Change the disabled state of the button.
|
||||
- `getVRDisplay():Promise` Returns a Promise returning the VRDisplay associated to the button.
|
||||
- `isPresenting():boolean`: Returns `true` if the canvas associated to the button is presenting in fullscreen or VR mode.
|
||||
- `requestEnterVR():Promise`: Requests to start presenting. Must be called from a user action ([read more](https://w3c.github.io/webvr/#dom-vrdisplay-requestpresent))
|
||||
- `requestEnterFullscreen():Promise`: Requests to enter fullscreen mode if its supported in the browser.
|
||||
- `requestExit():Promise`: Request exiting presentation mode.
|
||||
|
||||
## Development
|
||||
To run the example, install dependencies
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
and start the watcher and server (available on [localhost:3000/examples/basic.html](http://localhost:3000/examples/basic.html))
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
|
||||
To build the transpiled es5 version of the library, run
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
and the library will be build to `build/webvr-ui.js`
|
||||
1516
node_modules/webvr-ui/build/webvr-ui.js
generated
vendored
Normal file
1516
node_modules/webvr-ui/build/webvr-ui.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
25
node_modules/webvr-ui/build/webvr-ui.min.js
generated
vendored
Normal file
25
node_modules/webvr-ui/build/webvr-ui.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
31
node_modules/webvr-ui/examples/aframe.html
generated
vendored
Normal file
31
node_modules/webvr-ui/examples/aframe.html
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!-- Origin Trial Token, feature = WebVR, origin = https://googlevr.github.io, expires = 2017-03-08 -->
|
||||
<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-03-08" content="Avj04jeNgDLWRsM4igk+VQv+mYTFHk+8PlUpFGhlKHBQ67cYkrCm1XqG68vNvw/LpzOZdTAm2G7AdL8V2GUjaAIAAABReyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXZyLmdpdGh1Yi5pbzo0NDMiLCJmZWF0dXJlIjoiV2ViVlIiLCJleHBpcnkiOjE0ODg5ODYzMjV9">
|
||||
|
||||
<title>WebVR UI | A-Frame Example</title>
|
||||
<script src="https://aframe.io/releases/0.4.0/aframe.min.js"></script>
|
||||
|
||||
<!-- Include WebVR UI -->
|
||||
<script src="../build/webvr-ui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a-scene webvr-ui="color: black; background: white;">
|
||||
<a-sphere position="0 1.25 -1" radius="1.25" color="#EF2D5E"></a-sphere>
|
||||
<a-box position="-1 0.5 1" rotation="0 45 0" width="1" height="1" depth="1" color="#4CC3D9"></a-box>
|
||||
<a-cylinder position="1 0.75 1" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
|
||||
<a-plane rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
|
||||
|
||||
<a-sky color="#ECECEC"></a-sky>
|
||||
<a-entity position="0 0 3.8">
|
||||
<a-camera></a-camera>
|
||||
</a-entity>
|
||||
</a-scene>
|
||||
|
||||
<!-- Github corner-->
|
||||
<div class="github-corner-wrap"><a href="https://github.com/googlevr/webvr-ui/blob/master/examples/aframe.html" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#000; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a></div><style>.github-corner-wrap{position: absolute; right:0; z-index: 1; top:0;} .github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
226
node_modules/webvr-ui/examples/basic.html
generated
vendored
Normal file
226
node_modules/webvr-ui/examples/basic.html
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>WebVR UI | Basic Example</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Origin Trial Token, feature = WebVR, origin = https://googlevr.github.io, expires = 2017-03-08 -->
|
||||
<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-03-08" content="Avj04jeNgDLWRsM4igk+VQv+mYTFHk+8PlUpFGhlKHBQ67cYkrCm1XqG68vNvw/LpzOZdTAm2G7AdL8V2GUjaAIAAABReyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXZyLmdpdGh1Yi5pbzo0NDMiLCJmZWF0dXJlIjoiV2ViVlIiLCJleHBpcnkiOjE0ODg5ODYzMjV9">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-family: 'Karla', sans-serif;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#ui {
|
||||
color: white;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
#button {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#exit {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
color: white;
|
||||
font-size: 25px;
|
||||
text-decoration: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#learn-more {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<!-- three.js library -->
|
||||
<script src="node_modules/three/build/three.js"></script>
|
||||
|
||||
<!-- VRControls.js applies the WebVR transformations to a three.js camera object. -->
|
||||
<script src="node_modules/three/examples/js/controls/VRControls.js"></script>
|
||||
|
||||
<!-- VREffect.js handles stereo camera setup and rendering. -->
|
||||
<script src="node_modules/three/examples/js/effects/VREffect.js"></script>
|
||||
|
||||
<!-- A polyfill for the WebVR API. -->
|
||||
<script src="node_modules/webvr-polyfill/build/webvr-polyfill.js"></script>
|
||||
|
||||
<!-- Include WebVR UI -->
|
||||
<script src="../build/webvr-ui.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="ui">
|
||||
<h1>WebVR UI Basic Example</h1>
|
||||
<p>Example showing how to enter VR and without headset</p>
|
||||
|
||||
<div id="button"></div>
|
||||
|
||||
<div id="help">
|
||||
<a href="#" onclick="enterVR.requestEnterFullscreen()">Try it without a headset</a>
|
||||
<span id="learn-more">
|
||||
or <a href="https://webvr.info" target="_blank">get set up in VR.</a>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" id="exit" onclick="enterVR.requestExit()">✕</a>
|
||||
|
||||
<!-- Github corner-->
|
||||
<div class="github-corner-wrap"><a href="https://github.com/googlevr/webvr-ui/blob/master/examples/basic.html" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#fff; color:#151513; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a></div><style>.github-corner-wrap{position: absolute; right:0; z-index: 1} .github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
// Setup three.js WebGL renderer.
|
||||
var renderer = new THREE.WebGLRenderer();
|
||||
|
||||
// Create perspective camera used in VR
|
||||
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
|
||||
|
||||
//
|
||||
// BUTTON SETUP
|
||||
//
|
||||
|
||||
// Create WebVR UI Enter VR Button
|
||||
var options = {
|
||||
color: 'white',
|
||||
background: false,
|
||||
corners: 'square'
|
||||
};
|
||||
|
||||
var enterVR = new webvrui.EnterVRButton(renderer.domElement, options)
|
||||
.on("enter", function(){
|
||||
console.log("enter VR")
|
||||
})
|
||||
.on("exit", function(){
|
||||
console.log("exit VR");
|
||||
camera.quaternion.set(0,0,0,1);
|
||||
camera.position.set(0,controls.userHeight,0);
|
||||
})
|
||||
.on("error", function(error){
|
||||
document.getElementById("learn-more").style.display = "inline";
|
||||
console.error(error)
|
||||
})
|
||||
.on("hide", function(){
|
||||
document.getElementById("ui").style.display = "none";
|
||||
// On iOS there is no button to close fullscreen mode, so we need to provide one
|
||||
if(enterVR.state == webvrui.State.PRESENTING_FULLSCREEN) document.getElementById("exit").style.display = "initial";
|
||||
})
|
||||
.on("show", function(){
|
||||
document.getElementById("ui").style.display = "inherit";
|
||||
document.getElementById("exit").style.display = "none";
|
||||
});
|
||||
|
||||
|
||||
// Add button to the #button element
|
||||
document.getElementById("button").appendChild(enterVR.domElement);
|
||||
|
||||
//
|
||||
// WEBGL SCENE SETUP
|
||||
//
|
||||
|
||||
// Append the canvas element created by the renderer to document body element.
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
// Create a three.js scene.
|
||||
var scene = new THREE.Scene();
|
||||
|
||||
// Create a three.js camera.
|
||||
var controls = new THREE.VRControls(camera);
|
||||
controls.standing = true;
|
||||
camera.position.y = controls.userHeight;
|
||||
|
||||
// Create VR Effect rendering in stereoscopic mode
|
||||
var effect = new THREE.VREffect(renderer);
|
||||
effect.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setPixelRatio(Math.floor(window.devicePixelRatio));
|
||||
|
||||
// Create 3D objects in scene.
|
||||
var geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
|
||||
var material = new THREE.MeshNormalMaterial();
|
||||
var cube = new THREE.Mesh(geometry, material);
|
||||
cube.position.set(0, controls.userHeight, -0.8);
|
||||
scene.add(cube);
|
||||
|
||||
// Hande canvas resizing
|
||||
window.addEventListener('resize', onResize, true);
|
||||
window.addEventListener('vrdisplaypresentchange', onResize, true);
|
||||
|
||||
function onResize(e) {
|
||||
effect.setSize(window.innerWidth, window.innerHeight);
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Get the HMD
|
||||
var animationDisplay;
|
||||
enterVR.getVRDisplay()
|
||||
.then(function(display) {
|
||||
animationDisplay = display;
|
||||
display.requestAnimationFrame(animate);
|
||||
})
|
||||
.catch(function(){
|
||||
// If there is no display available, fallback to window
|
||||
animationDisplay = window;
|
||||
window.requestAnimationFrame(animate);
|
||||
});
|
||||
|
||||
// Request animation frame loop function
|
||||
var lastRender = 0;
|
||||
function animate(timestamp) {
|
||||
var delta = Math.min(timestamp - lastRender, 500);
|
||||
lastRender = timestamp;
|
||||
|
||||
// Apply rotation to cube mesh
|
||||
cube.rotation.y += delta * 0.0003;
|
||||
|
||||
if(enterVR.isPresenting()){
|
||||
controls.update();
|
||||
renderer.render(scene,camera);
|
||||
effect.render(scene, camera);
|
||||
} else {
|
||||
renderer.render(scene,camera);
|
||||
}
|
||||
animationDisplay.requestAnimationFrame(animate);
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
242
node_modules/webvr-ui/examples/customDom.html
generated
vendored
Normal file
242
node_modules/webvr-ui/examples/customDom.html
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>WebVR UI | Custom DOM Example</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- Origin Trial Token, feature = WebVR, origin = https://googlevr.github.io, expires = 2017-03-08 -->
|
||||
<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-03-08" content="Avj04jeNgDLWRsM4igk+VQv+mYTFHk+8PlUpFGhlKHBQ67cYkrCm1XqG68vNvw/LpzOZdTAm2G7AdL8V2GUjaAIAAABReyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXZyLmdpdGh1Yi5pbzo0NDMiLCJmZWF0dXJlIjoiV2ViVlIiLCJleHBpcnkiOjE0ODg5ODYzMjV9">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-family: 'Karla', sans-serif;
|
||||
}
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
p {
|
||||
margin:0;
|
||||
}
|
||||
#ui {
|
||||
color: white;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
#button {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<!-- three.js library -->
|
||||
<script src="node_modules/three/build/three.js"></script>
|
||||
|
||||
<!-- VRControls.js applies the WebVR transformations to a three.js camera object. -->
|
||||
<script src="node_modules/three/examples/js/controls/VRControls.js"></script>
|
||||
|
||||
<!-- VREffect.js handles stereo camera setup and rendering. -->
|
||||
<script src="node_modules/three/examples/js/effects/VREffect.js"></script>
|
||||
|
||||
<!-- A polyfill for the WebVR API. -->
|
||||
<script src="node_modules/webvr-polyfill/build/webvr-polyfill.js"></script>
|
||||
|
||||
<!-- Include WebVR UI -->
|
||||
<script src="../build/webvr-ui.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="ui">
|
||||
<h1>WebVR UI Custom DOM Example</h1>
|
||||
<p>Example showing how to use the library with custom dom elements</p>
|
||||
|
||||
<button id="button" class="webvr-ui-button"><span class="webvr-ui-title"></span></button>
|
||||
</div>
|
||||
|
||||
<!-- Github corner-->
|
||||
<div class="github-corner-wrap"><a href="https://github.com/googlevr/webvr-ui/blob/master/examples/basic.html" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#fff; color:#151513; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a></div><style>.github-corner-wrap{position: absolute; right:0; z-index: 1} .github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
// Setup three.js WebGL renderer.
|
||||
var renderer = new THREE.WebGLRenderer();
|
||||
|
||||
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
|
||||
|
||||
//
|
||||
// BUTTON SETUP
|
||||
//
|
||||
|
||||
//these will be used on each button in this example
|
||||
var onEnter = function(){ console.log("enter VR") };
|
||||
var onExit = function() {
|
||||
console.log("exit VR");
|
||||
camera.quaternion.set(0, 0, 0, 1);
|
||||
camera.position.set(0, controls.userHeight, 0);
|
||||
};
|
||||
|
||||
|
||||
// Create WebVR UI Enter VR Button
|
||||
var enterVR = new webvrui.EnterVRButton(renderer.domElement, {
|
||||
domElement: document.getElementById("button")
|
||||
});
|
||||
|
||||
enterVR
|
||||
.on("enter", onEnter)
|
||||
.on("exit", onExit);
|
||||
|
||||
|
||||
|
||||
//create an empty custom element and apply the styles we want for it
|
||||
var customButton = document.createElement("button");
|
||||
|
||||
//apply all of these styles
|
||||
var styles = {
|
||||
cursor: "pointer",
|
||||
margin: "10px auto",
|
||||
display: "block",
|
||||
color: "white",
|
||||
width: "64px",
|
||||
height: "64px",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
||||
outline: "none",
|
||||
border: "none"
|
||||
};
|
||||
|
||||
for (var prop in styles) {
|
||||
customButton.style[prop] = styles[prop];
|
||||
}
|
||||
|
||||
//we'll inject the right VR SVG Icon based on whether they have VR or not
|
||||
var vrIcon;
|
||||
|
||||
var enterVRCustom = new webvrui.EnterVRButton(renderer.domElement, {
|
||||
domElement: customButton
|
||||
});
|
||||
|
||||
enterVRCustom.on("ready", function(){
|
||||
vrIcon = webvrui.dom.createVRIcon("", 24);
|
||||
vrIcon.setAttribute("fill", "white");
|
||||
enterVRCustom.domElement.innerHTML = "";
|
||||
enterVRCustom.domElement.appendChild(vrIcon);
|
||||
});
|
||||
|
||||
enterVRCustom.on("enter", function(){
|
||||
enterVRCustom.domElement.removeChild(vrIcon);
|
||||
enterVRCustom.domElement.innerHTML = "EXIT";
|
||||
});
|
||||
|
||||
enterVRCustom.on('error', function(e){
|
||||
if(vrIcon && enterVRCustom.domElement.contains(vrIcon)) {
|
||||
enterVRCustom.domElement.removeChild(vrIcon);
|
||||
}
|
||||
vrIcon = webvrui.dom.createNoVRIcon('', 24);
|
||||
vrIcon.setAttribute("fill", "rgba(255, 255, 255, 0.5)");
|
||||
vrIcon.style.paddingTop = "4px";
|
||||
enterVRCustom.domElement.style.cursor = "inherit";
|
||||
enterVRCustom.domElement.appendChild(vrIcon);
|
||||
});
|
||||
|
||||
enterVRCustom
|
||||
.on('enter', onEnter)
|
||||
.on('exit', onExit);
|
||||
|
||||
document.getElementById("ui").appendChild(enterVRCustom.domElement);
|
||||
|
||||
//
|
||||
// WEBGL SCENE SETUP
|
||||
//
|
||||
|
||||
|
||||
// Append the canvas element created by the renderer to document body element.
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
|
||||
// Create a three.js scene.
|
||||
var scene = new THREE.Scene();
|
||||
|
||||
// Create a three.js camera.
|
||||
var controls = new THREE.VRControls(camera);
|
||||
controls.standing = true;
|
||||
camera.position.y = controls.userHeight;
|
||||
|
||||
// Create VR Effect rendering in stereoscopic mode
|
||||
var effect = new THREE.VREffect(renderer);
|
||||
effect.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setPixelRatio(Math.floor(window.devicePixelRatio));
|
||||
|
||||
// Create 3D objects in scene.
|
||||
var geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
|
||||
var material = new THREE.MeshNormalMaterial();
|
||||
var cube = new THREE.Mesh(geometry, material);
|
||||
cube.position.set(0, controls.userHeight, -0.8);
|
||||
scene.add(cube);
|
||||
|
||||
// Hande canvas resizing
|
||||
window.addEventListener('resize', onResize, true);
|
||||
window.addEventListener('vrdisplaypresentchange', onResize, true);
|
||||
|
||||
function onResize(e) {
|
||||
effect.setSize(window.innerWidth, window.innerHeight);
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Get the HMD
|
||||
var animationDisplay;
|
||||
enterVR.getVRDisplay()
|
||||
.then(function(display) {
|
||||
animationDisplay = display;
|
||||
display.requestAnimationFrame(animate);
|
||||
})
|
||||
.catch(function(){
|
||||
// If there is no display available, fallback to window
|
||||
animationDisplay = window;
|
||||
window.requestAnimationFrame(animate);
|
||||
});
|
||||
|
||||
|
||||
// Request animation frame loop function
|
||||
var lastRender = 0;
|
||||
function animate(timestamp) {
|
||||
var delta = Math.min(timestamp - lastRender, 500);
|
||||
lastRender = timestamp;
|
||||
// Apply rotation to cube mesh
|
||||
cube.rotation.y += delta * 0.0003;
|
||||
|
||||
if(enterVR.isPresenting() || enterVRCustom.isPresenting()){
|
||||
controls.update();
|
||||
renderer.render(scene,camera);
|
||||
effect.render(scene, camera);
|
||||
} else {
|
||||
renderer.render(scene,camera);
|
||||
}
|
||||
animationDisplay.requestAnimationFrame(animate);
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
26
node_modules/webvr-ui/examples/package.json
generated
vendored
Normal file
26
node_modules/webvr-ui/examples/package.json
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "webvr-ui-example",
|
||||
"version": "0.0.1",
|
||||
"description": "Example of using WebVR UI Library",
|
||||
"authors": [
|
||||
"Kyle Phillips <kylephillips@google.com>",
|
||||
"Jonas Jongejan <jongejan@google.com>"
|
||||
],
|
||||
"dependencies": {
|
||||
"three": "^0.84.0",
|
||||
"webvr-polyfill": "^0.9.25"
|
||||
},
|
||||
"keywords": [
|
||||
"vr",
|
||||
"webvr"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"browserify": {
|
||||
"transform": [
|
||||
"babelify"
|
||||
]
|
||||
},
|
||||
"directories": {
|
||||
"example": "example"
|
||||
}
|
||||
}
|
||||
247
node_modules/webvr-ui/examples/styling.html
generated
vendored
Normal file
247
node_modules/webvr-ui/examples/styling.html
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>WebVR UI | Styling Example</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Origin Trial Token, feature = WebVR, origin = https://googlevr.github.io, expires = 2017-03-08 -->
|
||||
<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-03-08" content="Avj04jeNgDLWRsM4igk+VQv+mYTFHk+8PlUpFGhlKHBQ67cYkrCm1XqG68vNvw/LpzOZdTAm2G7AdL8V2GUjaAIAAABReyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXZyLmdpdGh1Yi5pbzo0NDMiLCJmZWF0dXJlIjoiV2ViVlIiLCJleHBpcnkiOjE0ODg5ODYzMjV9">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-family: 'Karla', sans-serif;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 50px;
|
||||
}
|
||||
|
||||
#ui {
|
||||
color: white;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top:20px;
|
||||
text-align: left;
|
||||
padding-left:20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.webvr-ui-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#exit {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
color: white;
|
||||
font-size: 25px;
|
||||
text-decoration: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<!-- three.js library -->
|
||||
<script src="node_modules/three/build/three.js"></script>
|
||||
|
||||
<!-- VRControls.js applies the WebVR transformations to a three.js camera object. -->
|
||||
<script src="node_modules/three/examples/js/controls/VRControls.js"></script>
|
||||
|
||||
<!-- VREffect.js handles stereo camera setup and rendering. -->
|
||||
<script src="node_modules/three/examples/js/effects/VREffect.js"></script>
|
||||
|
||||
<!-- A polyfill for the WebVR API. -->
|
||||
<script src="node_modules/webvr-polyfill/build/webvr-polyfill.js"></script>
|
||||
|
||||
<!-- Include WebVR UI -->
|
||||
<script src="../build/webvr-ui.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="ui">
|
||||
<h1>WebVR UI Styling Example</h1>
|
||||
<p>Example showing how to the Enter VR button can be styled in different ways through options</p>
|
||||
</div>
|
||||
<a href="#" id="exit" onclick="enterVR.requestExit()">✕</a>
|
||||
|
||||
|
||||
<!-- Github corner-->
|
||||
<div class="github-corner-wrap"><a href="https://github.com/googlevr/webvr-ui/blob/master/examples/styling.html" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#fff; color:#151513; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a></div><style>.github-corner-wrap{position: absolute; right:0; z-index: 1} .github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
// Setup three.js WebGL renderer.
|
||||
var renderer = new THREE.WebGLRenderer();
|
||||
|
||||
// Create perspective camera used in VR
|
||||
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
|
||||
|
||||
//
|
||||
// BUTTON SETUP
|
||||
//
|
||||
|
||||
// Create WebVR UI Enter VR Button
|
||||
var options = [{
|
||||
color: 'white',
|
||||
},{
|
||||
color: 'black',
|
||||
background: 'orange',
|
||||
}, {
|
||||
color: 'black',
|
||||
background: 'white',
|
||||
corners: 'round'
|
||||
},{
|
||||
color: 'orange',
|
||||
corners: 'round'
|
||||
},{
|
||||
color: 'white',
|
||||
textEnterVRTitle: 'START',
|
||||
textExitVRTitle: 'EXIT',
|
||||
textVRNotFoundTitle: "ERROR"
|
||||
}];
|
||||
|
||||
var uiDom = document.getElementById("ui");
|
||||
var vrButtons = [];
|
||||
options.forEach(function(option,idx){
|
||||
var container = document.createElement("div");
|
||||
container.classList.add("button");
|
||||
uiDom.appendChild(container);
|
||||
|
||||
// Create description <pre>
|
||||
var description = document.createElement("pre");
|
||||
description.innerText = JSON.stringify(option, null, ' ');
|
||||
|
||||
// Force different css prefixes for each button
|
||||
option.cssprefix = 'webvr-ui-'+idx;
|
||||
|
||||
// Create button
|
||||
var enterVR = new webvrui.EnterVRButton(renderer.domElement, option)
|
||||
.on("hide", function(){
|
||||
document.getElementById("ui").style.display = "none";
|
||||
// On iOS there is no button to close fullscreen mode, so we need to provide one
|
||||
if(enterVR.state == webvrui.State.PRESENTING_FULLSCREEN) document.getElementById("exit").style.display = "initial";
|
||||
})
|
||||
.on("show", function(){
|
||||
document.getElementById("ui").style.display = "inherit";
|
||||
document.getElementById("exit").style.display = "none";
|
||||
});
|
||||
|
||||
vrButtons.push(enterVR);
|
||||
container.appendChild(enterVR.domElement);
|
||||
|
||||
container.appendChild(description)
|
||||
});
|
||||
|
||||
//
|
||||
// WEBGL SCENE SETUP
|
||||
//
|
||||
|
||||
// Append the canvas element created by the renderer to document body element.
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
// Create a three.js scene.
|
||||
var scene = new THREE.Scene();
|
||||
|
||||
// Create a three.js camera.
|
||||
var controls = new THREE.VRControls(camera);
|
||||
controls.standing = true;
|
||||
camera.position.y = controls.userHeight;
|
||||
|
||||
// Create VR Effect rendering in stereoscopic mode
|
||||
var effect = new THREE.VREffect(renderer);
|
||||
effect.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setPixelRatio(Math.floor(window.devicePixelRatio));
|
||||
|
||||
// Create 3D objects in scene.
|
||||
var geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
|
||||
var material = new THREE.MeshNormalMaterial();
|
||||
var cube = new THREE.Mesh(geometry, material);
|
||||
cube.position.set(0, controls.userHeight, -0.8);
|
||||
scene.add(cube);
|
||||
|
||||
// Hande canvas resizing
|
||||
window.addEventListener('resize', onResize, true);
|
||||
window.addEventListener('vrdisplaypresentchange', onResize, true);
|
||||
|
||||
function onResize(e) {
|
||||
effect.setSize(window.innerWidth, window.innerHeight);
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Get the HMD
|
||||
var animationDisplay;
|
||||
webvrui.WebVRManager.getVRDisplay()
|
||||
.then(function(display) {
|
||||
animationDisplay = display;
|
||||
display.requestAnimationFrame(animate);
|
||||
})
|
||||
.catch(function(){
|
||||
// If there is no display available, fallback to window
|
||||
animationDisplay = window;
|
||||
window.requestAnimationFrame(animate);
|
||||
});
|
||||
|
||||
// Request animation frame loop function
|
||||
var lastRender = 0;
|
||||
function animate(timestamp) {
|
||||
var delta = Math.min(timestamp - lastRender, 500);
|
||||
lastRender = timestamp;
|
||||
|
||||
// Apply rotation to cube mesh
|
||||
cube.rotation.y += delta * 0.0003;
|
||||
|
||||
if(vrButtons[0].isPresenting()){
|
||||
controls.update();
|
||||
renderer.render(scene,camera);
|
||||
effect.render(scene, camera);
|
||||
} else {
|
||||
renderer.render(scene,camera);
|
||||
}
|
||||
animationDisplay.requestAnimationFrame(animate);
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
22
node_modules/webvr-ui/examples/yarn.lock
generated
vendored
Normal file
22
node_modules/webvr-ui/examples/yarn.lock
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
eventemitter3@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.2.tgz#20ce4891909ce9f35b088c94fab40e2c96f473ac"
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
three@^0.84.0:
|
||||
version "0.84.0"
|
||||
resolved "https://registry.yarnpkg.com/three/-/three-0.84.0.tgz#95be85a55a0fa002aa625ed559130957dcffd918"
|
||||
|
||||
webvr-polyfill@^0.9.25:
|
||||
version "0.9.25"
|
||||
resolved "https://registry.yarnpkg.com/webvr-polyfill/-/webvr-polyfill-0.9.25.tgz#0ac1c4bff5433893ac7335144f8aca164cb397fa"
|
||||
dependencies:
|
||||
eventemitter3 "^2.0.2"
|
||||
object-assign "^4.0.1"
|
||||
119
node_modules/webvr-ui/package.json
generated
vendored
Normal file
119
node_modules/webvr-ui/package.json
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
{
|
||||
"raw": "webvr-ui@latest",
|
||||
"scope": null,
|
||||
"escapedName": "webvr-ui",
|
||||
"name": "webvr-ui",
|
||||
"rawSpec": "latest",
|
||||
"spec": "latest",
|
||||
"type": "tag"
|
||||
},
|
||||
"/Users/smus/Projects/webvr-boilerplate"
|
||||
]
|
||||
],
|
||||
"_from": "webvr-ui@latest",
|
||||
"_id": "webvr-ui@0.9.3",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/webvr-ui",
|
||||
"_nodeVersion": "7.4.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-18-east.internal.npmjs.com",
|
||||
"tmp": "tmp/webvr-ui-0.9.3.tgz_1485458579749_0.7110568033531308"
|
||||
},
|
||||
"_npmUser": {
|
||||
"name": "creativelab-package",
|
||||
"email": "googlecreativelab-packages@googlegroups.com"
|
||||
},
|
||||
"_npmVersion": "4.0.5",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"raw": "webvr-ui@latest",
|
||||
"scope": null,
|
||||
"escapedName": "webvr-ui",
|
||||
"name": "webvr-ui",
|
||||
"rawSpec": "latest",
|
||||
"spec": "latest",
|
||||
"type": "tag"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/webvr-ui/-/webvr-ui-0.9.3.tgz",
|
||||
"_shasum": "4077ab0b9cf1909aa23a2dd873266732fa0dccbb",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "webvr-ui@latest",
|
||||
"_where": "/Users/smus/Projects/webvr-boilerplate",
|
||||
"authors": [
|
||||
"Kyle Phillips <kylephillips@google.com>",
|
||||
"Jonas Jongejan <jongejan@google.com>"
|
||||
],
|
||||
"browserify": {
|
||||
"transform": [
|
||||
[
|
||||
"babelify",
|
||||
{
|
||||
"presets": [
|
||||
"es2015"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/googlevr/webvr-ui/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"eventemitter3": "^2.0.2",
|
||||
"screenfull": "^3.0.2"
|
||||
},
|
||||
"description": "Library that creates a UI wrapping the WebVR experience",
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "^6.16.0",
|
||||
"babelify": "^7.3.0",
|
||||
"browserify": "^14.0.0",
|
||||
"budo": "^9.2.1",
|
||||
"derequire": "^2.0.3",
|
||||
"eslint": "^3.13.1",
|
||||
"eslint-config-google": "^0.7.1",
|
||||
"tape": "^4.6.2",
|
||||
"uglifyify": "^3.0.4"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "4077ab0b9cf1909aa23a2dd873266732fa0dccbb",
|
||||
"tarball": "https://registry.npmjs.org/webvr-ui/-/webvr-ui-0.9.3.tgz"
|
||||
},
|
||||
"gitHead": "01ce7e7ab3a9b17d37e1cb0850c6ba8f2053034e",
|
||||
"homepage": "https://github.com/googlevr/webvr-ui#readme",
|
||||
"keywords": [
|
||||
"vr",
|
||||
"webvr"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"main": "src/index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "creativelab-package",
|
||||
"email": "googlecreativelab-packages@googlegroups.com"
|
||||
}
|
||||
],
|
||||
"name": "webvr-ui",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/googlevr/webvr-ui.git"
|
||||
},
|
||||
"scripts": {
|
||||
"browserify": "browserify src/index.js --standalone webvrui | derequire > build/webvr-ui.js",
|
||||
"browserifymin": "browserify -g uglifyify src/index.js --standalone webvrui | derequire > build/webvr-ui.min.js",
|
||||
"build": "npm run browserify & npm run browserifymin",
|
||||
"lint": "eslint -c .eslintrc.json src",
|
||||
"prepublish": "npm run lint && npm run build",
|
||||
"start": "budo src/index.js:build/webvr-ui.js --live --verbose --port 3000 -- --standalone webvrui"
|
||||
},
|
||||
"version": "0.9.3"
|
||||
}
|
||||
92
node_modules/webvr-ui/src/aframe-component.js
generated
vendored
Normal file
92
node_modules/webvr-ui/src/aframe-component.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* global AFRAME */
|
||||
|
||||
import EnterVRButton from './enter-vr-button';
|
||||
import State from './states';
|
||||
|
||||
if (typeof AFRAME !== 'undefined' && AFRAME) {
|
||||
AFRAME.registerComponent('webvr-ui', {
|
||||
dependencies: ['canvas'],
|
||||
|
||||
schema: {
|
||||
enabled: {type: 'boolean', default: true},
|
||||
color: {type: 'string', default: 'white'},
|
||||
background: {type: 'string', default: 'black'},
|
||||
corners: {type: 'string', default: 'square'},
|
||||
disabledOpacity: {type: 'number', default: 0.5},
|
||||
|
||||
textEnterVRTitle: {type: 'string'},
|
||||
textExitVRTitle: {type: 'string'},
|
||||
textVRNotFoundTitle: {type: 'string'},
|
||||
},
|
||||
|
||||
init: function() {
|
||||
},
|
||||
|
||||
update: function() {
|
||||
let scene = document.querySelector('a-scene');
|
||||
scene.setAttribute('vr-mode-ui', {enabled: !this.data.enabled});
|
||||
|
||||
if (this.data.enabled) {
|
||||
if (this.enterVREl) {
|
||||
return;
|
||||
}
|
||||
|
||||
let options = {
|
||||
color: this.data.color,
|
||||
background: this.data.background,
|
||||
corners: this.data.corners,
|
||||
disabledOpacity: this.data.disabledOpacity,
|
||||
textEnterVRTitle: this.data.textEnterVRTitle,
|
||||
textExitVRTitle: this.data.textExitVRTitle,
|
||||
textVRNotFoundTitle: this.data.textVRNotFoundTitle,
|
||||
onRequestStateChange: function(state) {
|
||||
if (state == State.PRESENTING) {
|
||||
scene.enterVR();
|
||||
} else {
|
||||
scene.exitVR();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
let enterVR = this.enterVR = new EnterVRButton(scene.canvas, options);
|
||||
|
||||
this.enterVREl = enterVR.domElement;
|
||||
|
||||
document.body.appendChild(enterVR.domElement);
|
||||
|
||||
enterVR.domElement.style.position = 'absolute';
|
||||
enterVR.domElement.style.bottom = '10px';
|
||||
enterVR.domElement.style.left = '50%';
|
||||
enterVR.domElement.style.transform = 'translate(-50%, -50%)';
|
||||
enterVR.domElement.style.textAlign = 'center';
|
||||
} else {
|
||||
if (this.enterVREl) {
|
||||
this.enterVREl.parentNode.removeChild(this.enterVREl);
|
||||
this.enterVR.remove();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
if (this.enterVREl) {
|
||||
this.enterVREl.parentNode.removeChild(this.enterVREl);
|
||||
this.enterVR.remove();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
230
node_modules/webvr-ui/src/dom.js
generated
vendored
Normal file
230
node_modules/webvr-ui/src/dom.js
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const _LOGO_SCALE = 0.8;
|
||||
let _WEBVR_UI_CSS_INJECTED = {};
|
||||
|
||||
/**
|
||||
* Generate the innerHTML for the button
|
||||
*
|
||||
* @return {string} html of the button as string
|
||||
* @param {string} cssPrefix
|
||||
* @param {Number} height
|
||||
* @private
|
||||
*/
|
||||
const generateInnerHTML = (cssPrefix, height)=> {
|
||||
const logoHeight = height*_LOGO_SCALE;
|
||||
const svgString = generateVRIconString(cssPrefix, logoHeight) + generateNoVRIconString(cssPrefix, logoHeight);
|
||||
|
||||
return `<button class="${cssPrefix}-button">
|
||||
<div class="${cssPrefix}-title"></div>
|
||||
<div class="${cssPrefix}-logo" >${svgString}</div>
|
||||
</button>`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject the CSS string to the head of the document
|
||||
*
|
||||
* @param {string} cssText the css to inject
|
||||
*/
|
||||
export const injectCSS = (cssText)=> {
|
||||
// Create the css
|
||||
const style = document.createElement('style');
|
||||
style.innerHTML = cssText;
|
||||
|
||||
let head = document.getElementsByTagName('head')[0];
|
||||
head.insertBefore(style, head.firstChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate DOM element view for button
|
||||
*
|
||||
* @return {HTMLElement}
|
||||
* @param {Object} options
|
||||
*/
|
||||
export const createDefaultView = (options)=> {
|
||||
const fontSize = options.height / 3;
|
||||
if (options.injectCSS) {
|
||||
// Check that css isnt already injected
|
||||
if (!_WEBVR_UI_CSS_INJECTED[options.cssprefix]) {
|
||||
injectCSS(generateCSS(options, fontSize));
|
||||
_WEBVR_UI_CSS_INJECTED[options.cssprefix] = true;
|
||||
}
|
||||
}
|
||||
|
||||
const el = document.createElement('div');
|
||||
el.innerHTML = generateInnerHTML(options.cssprefix, fontSize);
|
||||
return el.firstChild;
|
||||
};
|
||||
|
||||
|
||||
export const createVRIcon = (cssPrefix, height)=>{
|
||||
const el = document.createElement('div');
|
||||
el.innerHTML = generateVRIconString(cssPrefix, height);
|
||||
return el.firstChild;
|
||||
};
|
||||
|
||||
export const createNoVRIcon = (cssPrefix, height)=>{
|
||||
const el = document.createElement('div');
|
||||
el.innerHTML = generateNoVRIconString(cssPrefix, height);
|
||||
return el.firstChild;
|
||||
};
|
||||
|
||||
|
||||
const generateVRIconString = (cssPrefix, height)=> {
|
||||
let aspect = 28 / 18;
|
||||
return `<svg class="${cssPrefix}-svg" version="1.1" x="0px" y="0px"
|
||||
width="${aspect * height}px" height="${height}px" viewBox="0 0 28 18" xml:space="preserve">
|
||||
<path d="M26.8,1.1C26.1,0.4,25.1,0,24.2,0H3.4c-1,0-1.7,0.4-2.4,1.1C0.3,1.7,0,2.7,0,3.6v10.7
|
||||
c0,1,0.3,1.9,0.9,2.6C1.6,17.6,2.4,18,3.4,18h5c0.7,0,1.3-0.2,1.8-0.5c0.6-0.3,1-0.8,1.3-1.4l
|
||||
1.5-2.6C13.2,13.1,13,13,14,13v0h-0.2 h0c0.3,0,0.7,0.1,0.8,0.5l1.4,2.6c0.3,0.6,0.8,1.1,1.3,
|
||||
1.4c0.6,0.3,1.2,0.5,1.8,0.5h5c1,0,2-0.4,2.7-1.1c0.7-0.7,1.2-1.6,1.2-2.6 V3.6C28,2.7,27.5,
|
||||
1.7,26.8,1.1z M7.4,11.8c-1.6,0-2.8-1.3-2.8-2.8c0-1.6,1.3-2.8,2.8-2.8c1.6,0,2.8,1.3,2.8,2.8
|
||||
C10.2,10.5,8.9,11.8,7.4,11.8z M20.1,11.8c-1.6,0-2.8-1.3-2.8-2.8c0-1.6,1.3-2.8,2.8-2.8C21.7
|
||||
,6.2,23,7.4,23,9 C23,10.5,21.7,11.8,20.1,11.8z"/>
|
||||
</svg>`;
|
||||
};
|
||||
|
||||
const generateNoVRIconString = (cssPrefix, height)=>{
|
||||
let aspect = 28 / 18;
|
||||
return `<svg class="${cssPrefix}-svg-error" x="0px" y="0px"
|
||||
width="${aspect * height}px" height="${aspect * height}px" viewBox="0 0 28 28" xml:space="preserve">
|
||||
<path d="M17.6,13.4c0-0.2-0.1-0.4-0.1-0.6c0-1.6,1.3-2.8,2.8-2.8s2.8,1.3,2.8,2.8s-1.3,2.8-2.8,2.8
|
||||
c-0.2,0-0.4,0-0.6-0.1l5.9,5.9c0.5-0.2,0.9-0.4,1.3-0.8
|
||||
c0.7-0.7,1.1-1.6,1.1-2.5V7.4c0-1-0.4-1.9-1.1-2.5c-0.7-0.7-1.6-1-2.5-1
|
||||
H8.1 L17.6,13.4z"/>
|
||||
<path d="M10.1,14.2c-0.5,0.9-1.4,1.4-2.4,1.4c-1.6,0-2.8-1.3-2.8-2.8c0-1.1,0.6-2,1.4-2.5
|
||||
L0.9,5.1 C0.3,5.7,0,6.6,0,7.5v10.7c0,1,0.4,1.8,1.1,2.5c0.7,0.7,1.6,1,2.5,1
|
||||
h5c0.7,0,1.3-0.1,1.8-0.5c0.6-0.3,1-0.8,1.3-1.4l1.3-2.6 L10.1,14.2z"/>
|
||||
<path d="M25.5,27.5l-25-25C-0.1,2-0.1,1,0.5,0.4l0,0C1-0.1,2-0.1,2.6,0.4l25,25c0.6,0.6,0.6,1.5
|
||||
,0,2.1l0,0 C27,28.1,26,28.1,25.5,27.5z"/>
|
||||
</svg>`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate the CSS string to inject
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Number} [fontSize=18]
|
||||
* @return {string}
|
||||
*/
|
||||
export const generateCSS = (options, fontSize=18)=> {
|
||||
const height = options.height;
|
||||
const borderWidth = 2;
|
||||
const borderColor = options.background ? options.background : options.color;
|
||||
const cssPrefix = options.cssprefix;
|
||||
|
||||
let borderRadius;
|
||||
if (options.corners == 'round') {
|
||||
borderRadius = options.height / 2;
|
||||
} else if (options.corners == 'square') {
|
||||
borderRadius = 2;
|
||||
} else {
|
||||
borderRadius = options.corners;
|
||||
}
|
||||
|
||||
return (`
|
||||
@font-face {
|
||||
font-family: 'Karla';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Karla'), local('Karla-Regular'),
|
||||
url(https://fonts.gstatic.com/s/karla/v5/31P4mP32i98D9CEnGyeX9Q.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Karla';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Karla'), local('Karla-Regular'),
|
||||
url(https://fonts.gstatic.com/s/karla/v5/Zi_e6rBgGqv33BWF8WTq8g.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074,
|
||||
U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
button.${cssPrefix}-button {
|
||||
font-family: 'Karla', sans-serif;
|
||||
|
||||
border: ${borderColor} ${borderWidth}px solid;
|
||||
border-radius: ${borderRadius}px;
|
||||
box-sizing: border-box;
|
||||
background: ${options.background ? options.background : 'none'};
|
||||
|
||||
height: ${height}px;
|
||||
min-width: ${fontSize * 9.6}px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button.${cssPrefix}-button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Logo
|
||||
*/
|
||||
|
||||
.${cssPrefix}-logo {
|
||||
width: ${height}px;
|
||||
height: ${height}px;
|
||||
position: absolute;
|
||||
top:0px;
|
||||
left:0px;
|
||||
width: ${height - 4}px;
|
||||
height: ${height - 4}px;
|
||||
}
|
||||
.${cssPrefix}-svg {
|
||||
fill: ${options.color};
|
||||
margin-top: ${(height - fontSize * _LOGO_SCALE) / 2 - 2}px;
|
||||
margin-left: ${height / 3 }px;
|
||||
}
|
||||
.${cssPrefix}-svg-error {
|
||||
fill: ${options.color};
|
||||
display:none;
|
||||
margin-top: ${(height - 28 / 18 * fontSize * _LOGO_SCALE) / 2 - 2}px;
|
||||
margin-left: ${height / 3 }px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Title
|
||||
*/
|
||||
|
||||
.${cssPrefix}-title {
|
||||
color: ${options.color};
|
||||
position: relative;
|
||||
font-size: ${fontSize}px;
|
||||
padding-left: ${height * 1.05}px;
|
||||
padding-right: ${(borderRadius - 10 < 5) ? height / 3 : borderRadius - 10}px;
|
||||
}
|
||||
|
||||
/*
|
||||
* disabled
|
||||
*/
|
||||
|
||||
button.${cssPrefix}-button[disabled=true] {
|
||||
opacity: ${options.disabledOpacity};
|
||||
}
|
||||
|
||||
button.${cssPrefix}-button[disabled=true] > .${cssPrefix}-logo > .${cssPrefix}-svg {
|
||||
display:none;
|
||||
}
|
||||
|
||||
button.${cssPrefix}-button[disabled=true] > .${cssPrefix}-logo > .${cssPrefix}-svg-error {
|
||||
display:initial;
|
||||
}
|
||||
`);
|
||||
};
|
||||
345
node_modules/webvr-ui/src/enter-vr-button.js
generated
vendored
Normal file
345
node_modules/webvr-ui/src/enter-vr-button.js
generated
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import WebVRManager from './webvr-manager';
|
||||
import {createDefaultView} from './dom';
|
||||
import State from './states';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
/**
|
||||
* A button to allow easy-entry and messaging around a WebVR experience
|
||||
* @class
|
||||
*/
|
||||
export default class EnterVRButton extends EventEmitter {
|
||||
/**
|
||||
* Construct a new Enter VR Button
|
||||
* @constructor
|
||||
* @param {HTMLCanvasElement} sourceCanvas the canvas that you want to present in WebVR
|
||||
* @param {Object} [options] optional parameters
|
||||
* @param {HTMLElement} [options.domElement] provide your own domElement to bind to
|
||||
* @param {Boolean} [options.injectCSS=true] set to false if you want to write your own styles
|
||||
* @param {Function} [options.beforeEnter] should return a promise, opportunity to intercept request to enter
|
||||
* @param {Function} [options.beforeExit] should return a promise, opportunity to intercept request to exit
|
||||
* @param {Function} [options.onRequestStateChange] set to a function returning false to prevent default state changes
|
||||
* @param {string} [options.textEnterVRTitle] set the text for Enter VR
|
||||
* @param {string} [options.textVRNotFoundTitle] set the text for when a VR display is not found
|
||||
* @param {string} [options.textExitVRTitle] set the text for exiting VR
|
||||
* @param {string} [options.color] text and icon color
|
||||
* @param {string} [options.background] set to false for no brackground or a color
|
||||
* @param {string} [options.corners] set to 'round', 'square' or pixel value representing the corner radius
|
||||
* @param {string} [options.disabledOpacity] set opacity of button dom when disabled
|
||||
* @param {string} [options.cssprefix] set to change the css prefix from default 'webvr-ui'
|
||||
*/
|
||||
constructor(sourceCanvas, options) {
|
||||
super();
|
||||
options = options || {};
|
||||
|
||||
options.color = options.color || 'rgb(80,168,252)';
|
||||
options.background = options.background || false;
|
||||
options.disabledOpacity = options.disabledOpacity || 0.5;
|
||||
options.height = options.height || 55;
|
||||
options.corners = options.corners || 'square';
|
||||
options.cssprefix = options.cssprefix || 'webvr-ui';
|
||||
|
||||
options.textEnterVRTitle = options.textEnterVRTitle || 'ENTER VR';
|
||||
options.textVRNotFoundTitle = options.textVRNotFoundTitle || 'VR NOT FOUND';
|
||||
options.textExitVRTitle = options.textExitVRTitle || 'EXIT VR';
|
||||
|
||||
options.onRequestStateChange = options.onRequestStateChange || (() => true);
|
||||
options.beforeEnter = options.beforeEnter || (()=> new Promise((resolve)=> resolve()));
|
||||
options.beforeExit = options.beforeExit || (()=> new Promise((resolve)=> resolve()));
|
||||
|
||||
options.injectCSS = options.injectCSS !== false;
|
||||
|
||||
this.options = options;
|
||||
|
||||
|
||||
this.sourceCanvas = sourceCanvas;
|
||||
|
||||
// Pass in your own domElement if you really dont want to use ours
|
||||
this.domElement = options.domElement || createDefaultView(options);
|
||||
this.__defaultDisplayStyle = this.domElement.style.display || 'initial';
|
||||
|
||||
// Create WebVR Manager
|
||||
this.manager = new WebVRManager();
|
||||
this.manager.checkDisplays();
|
||||
this.manager.addListener('change', (state)=> this.__onStateChange(state));
|
||||
|
||||
// Bind button click events to __onClick
|
||||
this.domElement.addEventListener('click', ()=> this.__onEnterVRClick());
|
||||
|
||||
this.__forceDisabled = false;
|
||||
this.setTitle(this.options.textEnterVRTitle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title of the button
|
||||
* @param {string} text
|
||||
* @return {EnterVRButton}
|
||||
*/
|
||||
setTitle(text) {
|
||||
this.domElement.title = text;
|
||||
ifChild(this.domElement, this.options.cssprefix, 'title', (title)=> {
|
||||
if (!text) {
|
||||
title.style.display = 'none';
|
||||
} else {
|
||||
title.innerText = text;
|
||||
title.style.display = 'initial';
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tooltip of the button
|
||||
* @param {string} tooltip
|
||||
* @return {EnterVRButton}
|
||||
*/
|
||||
setTooltip(tooltip) {
|
||||
this.domElement.title = tooltip;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the button
|
||||
* @return {EnterVRButton}
|
||||
*/
|
||||
show() {
|
||||
this.domElement.style.display = this.__defaultDisplayStyle;
|
||||
this.emit('show');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the button
|
||||
* @return {EnterVRButton}
|
||||
*/
|
||||
hide() {
|
||||
this.domElement.style.display = 'none';
|
||||
this.emit('hide');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the button
|
||||
* @return {EnterVRButton}
|
||||
*/
|
||||
enable() {
|
||||
this.__setDisabledAttribute(false);
|
||||
this.__forceDisabled = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the button from being clicked
|
||||
* @return {EnterVRButton}
|
||||
*/
|
||||
disable() {
|
||||
this.__setDisabledAttribute(true);
|
||||
this.__forceDisabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up object for garbage collection
|
||||
*/
|
||||
remove() {
|
||||
this.manager.remove();
|
||||
|
||||
if (this.domElement.parentElement) {
|
||||
this.domElement.parentElement.removeChild(this.domElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise getting the VRDisplay used
|
||||
* @return {Promise.<VRDisplay>}
|
||||
*/
|
||||
getVRDisplay() {
|
||||
return WebVRManager.getVRDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the canvas the button is connected to is currently presenting
|
||||
* @return {boolean}
|
||||
*/
|
||||
isPresenting() {
|
||||
return this.state === State.PRESENTING || this.state == State.PRESENTING_FULLSCREEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request entering VR
|
||||
* @return {Promise}
|
||||
*/
|
||||
requestEnterVR() {
|
||||
return new Promise((resolve, reject)=> {
|
||||
if (this.options.onRequestStateChange(State.PRESENTING)) {
|
||||
return this.options.beforeEnter()
|
||||
.then(()=> this.manager.enterVR(this.manager.defaultDisplay, this.sourceCanvas))
|
||||
.then(resolve);
|
||||
} else {
|
||||
reject(new Error(State.ERROR_REQUEST_STATE_CHANGE_REJECTED));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Request exiting presentation mode
|
||||
* @return {Promise}
|
||||
*/
|
||||
requestExit() {
|
||||
const initialState = this.state;
|
||||
|
||||
return new Promise((resolve, reject)=> {
|
||||
if (this.options.onRequestStateChange(State.READY_TO_PRESENT)) {
|
||||
return this.options.beforeExit()
|
||||
.then(()=>
|
||||
// if we were presenting VR, exit VR, if we are
|
||||
// exiting fullscreen, exit fullscreen
|
||||
initialState === State.PRESENTING ?
|
||||
this.manager.exitVR(this.manager.defaultDisplay) :
|
||||
this.manager.exitFullscreen())
|
||||
.then(resolve);
|
||||
} else {
|
||||
reject(new Error(State.ERROR_REQUEST_STATE_CHANGE_REJECTED));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Request entering the site in fullscreen, but not VR
|
||||
* @return {Promise}
|
||||
*/
|
||||
requestEnterFullscreen() {
|
||||
return new Promise((resolve, reject)=> {
|
||||
if (this.options.onRequestStateChange(State.PRESENTING_FULLSCREEN)) {
|
||||
return this.options.beforeEnter()
|
||||
.then(()=>this.manager.enterFullscreen(this.sourceCanvas))
|
||||
.then(resolve);
|
||||
} else {
|
||||
reject(new Error(State.ERROR_REQUEST_STATE_CHANGE_REJECTED));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the disabled attribute
|
||||
* @param {boolean} disabled
|
||||
* @private
|
||||
*/
|
||||
__setDisabledAttribute(disabled) {
|
||||
if (disabled || this.__forceDisabled) {
|
||||
this.domElement.setAttribute('disabled', 'true');
|
||||
} else {
|
||||
this.domElement.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handling click event from button
|
||||
* @private
|
||||
*/
|
||||
__onEnterVRClick() {
|
||||
if (this.state == State.READY_TO_PRESENT) {
|
||||
this.requestEnterVR();
|
||||
} else if (this.isPresenting()) {
|
||||
this.requestExit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {State} state the state that its transitioning to
|
||||
* @private
|
||||
*/
|
||||
__onStateChange(state) {
|
||||
if (state != this.state) {
|
||||
if (this.state === State.PRESENTING || this.state === State.PRESENTING_FULLSCREEN) {
|
||||
this.emit('exit');
|
||||
}
|
||||
this.state = state;
|
||||
|
||||
switch (state) {
|
||||
case State.READY_TO_PRESENT:
|
||||
this.show();
|
||||
this.setTitle(this.options.textEnterVRTitle);
|
||||
if (this.manager.defaultDisplay) {
|
||||
this.setTooltip('Enter VR using ' + this.manager.defaultDisplay.displayName);
|
||||
}
|
||||
this.__setDisabledAttribute(false);
|
||||
this.emit('ready');
|
||||
break;
|
||||
|
||||
case State.PRESENTING:
|
||||
case State.PRESENTING_FULLSCREEN:
|
||||
if (!this.manager.defaultDisplay ||
|
||||
!this.manager.defaultDisplay.capabilities.hasExternalDisplay ||
|
||||
state == State.PRESENTING_FULLSCREEN) {
|
||||
this.hide();
|
||||
}
|
||||
this.setTitle(this.options.textExitVRTitle);
|
||||
this.__setDisabledAttribute(false);
|
||||
this.emit('enter');
|
||||
break;
|
||||
|
||||
// Error states
|
||||
case State.ERROR_BROWSER_NOT_SUPPORTED:
|
||||
this.show();
|
||||
this.setTitle(this.options.textVRNotFoundTitle);
|
||||
this.setTooltip('Browser not supported');
|
||||
this.__setDisabledAttribute(true);
|
||||
this.emit('error', new Error(state));
|
||||
break;
|
||||
|
||||
case State.ERROR_NO_PRESENTABLE_DISPLAYS:
|
||||
this.show();
|
||||
this.setTitle(this.options.textVRNotFoundTitle);
|
||||
this.setTooltip('No VR headset found.');
|
||||
this.__setDisabledAttribute(true);
|
||||
this.emit('error', new Error(state));
|
||||
break;
|
||||
|
||||
case State.ERROR_REQUEST_TO_PRESENT_REJECTED:
|
||||
this.show();
|
||||
this.setTitle(this.options.textVRNotFoundTitle);
|
||||
this.setTooltip('Something went wrong trying to start presenting to your headset.');
|
||||
this.__setDisabledAttribute(true);
|
||||
this.emit('error', new Error(state));
|
||||
break;
|
||||
|
||||
case State.ERROR_EXIT_PRESENT_REJECTED:
|
||||
default:
|
||||
this.show();
|
||||
this.setTitle(this.options.textVRNotFoundTitle);
|
||||
this.setTooltip('Unknown error.');
|
||||
this.__setDisabledAttribute(true);
|
||||
this.emit('error', new Error(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function checking if a specific css class exists as child of element.
|
||||
*
|
||||
* @param {HTMLElement} el element to find child in
|
||||
* @param {string} cssPrefix css prefix of button
|
||||
* @param {string} suffix class name
|
||||
* @param {function} fn function to call if child is found
|
||||
* @private
|
||||
*/
|
||||
const ifChild = (el, cssPrefix, suffix, fn)=> {
|
||||
const c = el.querySelector('.' + cssPrefix + '-' + suffix);
|
||||
c && fn(c);
|
||||
};
|
||||
26
node_modules/webvr-ui/src/index.js
generated
vendored
Normal file
26
node_modules/webvr-ui/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import WebVRManager from './webvr-manager';
|
||||
import State from './states';
|
||||
import * as dom from './dom';
|
||||
import EnterVRButton from './enter-vr-button';
|
||||
import './aframe-component';
|
||||
|
||||
export {
|
||||
EnterVRButton,
|
||||
dom,
|
||||
State,
|
||||
WebVRManager,
|
||||
};
|
||||
44
node_modules/webvr-ui/src/states.js
generated
vendored
Normal file
44
node_modules/webvr-ui/src/states.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Not yet presenting, but ready to present
|
||||
const READY_TO_PRESENT = 'ready';
|
||||
|
||||
// In presentation mode
|
||||
const PRESENTING = 'presenting';
|
||||
const PRESENTING_FULLSCREEN = 'presenting-fullscreen';
|
||||
|
||||
// Checking device availability
|
||||
const PREPARING = 'preparing';
|
||||
|
||||
// Errors
|
||||
const ERROR_NO_PRESENTABLE_DISPLAYS = 'error-no-presentable-displays';
|
||||
const ERROR_BROWSER_NOT_SUPPORTED = 'error-browser-not-supported';
|
||||
const ERROR_REQUEST_TO_PRESENT_REJECTED = 'error-request-to-present-rejected';
|
||||
const ERROR_EXIT_PRESENT_REJECTED = 'error-exit-present-rejected';
|
||||
const ERROR_REQUEST_STATE_CHANGE_REJECTED = 'error-request-state-change-rejected';
|
||||
const ERROR_UNKOWN = 'error-unkown';
|
||||
|
||||
export default {
|
||||
READY_TO_PRESENT,
|
||||
PRESENTING,
|
||||
PRESENTING_FULLSCREEN,
|
||||
PREPARING,
|
||||
ERROR_NO_PRESENTABLE_DISPLAYS,
|
||||
ERROR_BROWSER_NOT_SUPPORTED,
|
||||
ERROR_REQUEST_TO_PRESENT_REJECTED,
|
||||
ERROR_EXIT_PRESENT_REJECTED,
|
||||
ERROR_REQUEST_STATE_CHANGE_REJECTED,
|
||||
ERROR_UNKOWN,
|
||||
};
|
||||
224
node_modules/webvr-ui/src/webvr-manager.js
generated
vendored
Normal file
224
node_modules/webvr-ui/src/webvr-manager.js
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import State from './states';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import screenfull from 'screenfull';
|
||||
|
||||
/**
|
||||
* WebVR Manager is a utility to handle VR displays
|
||||
*/
|
||||
export default class WebVRManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Construct a new WebVRManager
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.state = State.PREPARING;
|
||||
|
||||
// Bind vr display present change event to __onVRDisplayPresentChange
|
||||
this.__onVRDisplayPresentChange = this.__onVRDisplayPresentChange.bind(this);
|
||||
window.addEventListener('vrdisplaypresentchange', this.__onVRDisplayPresentChange);
|
||||
|
||||
this.__onChangeFullscreen = this.__onChangeFullscreen.bind(this);
|
||||
if (screenfull.enabled) {
|
||||
document.addEventListener(screenfull.raw.fullscreenchange, this.__onChangeFullscreen);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the browser is compatible with WebVR and has headsets.
|
||||
* @return {Promise<VRDisplay>}
|
||||
*/
|
||||
checkDisplays() {
|
||||
return WebVRManager.getVRDisplay()
|
||||
.then((display) => {
|
||||
this.defaultDisplay = display;
|
||||
this.__setState(State.READY_TO_PRESENT);
|
||||
return display;
|
||||
})
|
||||
.catch((e) => {
|
||||
delete this.defaultDisplay;
|
||||
if (e.name == 'NO_DISPLAYS') {
|
||||
this.__setState(State.ERROR_NO_PRESENTABLE_DISPLAYS);
|
||||
} else if (e.name == 'WEBVR_UNSUPPORTED') {
|
||||
this.__setState(State.ERROR_BROWSER_NOT_SUPPORTED);
|
||||
} else {
|
||||
this.__setState(State.ERROR_UNKOWN);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up object for garbage collection
|
||||
*/
|
||||
remove() {
|
||||
window.removeEventListener('vrdisplaypresentchange', this.__onVRDisplayPresentChange);
|
||||
if (screenfull.enabled) {
|
||||
document.removeEventListener(screenfull.raw.fullscreenchanged, this.__onChangeFullscreen);
|
||||
}
|
||||
|
||||
this.removeAllListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns promise returning list of available VR displays.
|
||||
* @return {Promise<VRDisplay>}
|
||||
*/
|
||||
static getVRDisplay() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!navigator || !navigator.getVRDisplays) {
|
||||
let e = new Error('Browser not supporting WebVR');
|
||||
e.name = 'WEBVR_UNSUPPORTED';
|
||||
reject(e);
|
||||
return;
|
||||
}
|
||||
|
||||
const rejectNoDisplay = ()=> {
|
||||
// No displays are found.
|
||||
let e = new Error('No displays found');
|
||||
e.name = 'NO_DISPLAYS';
|
||||
reject(e);
|
||||
};
|
||||
|
||||
navigator.getVRDisplays().then(
|
||||
function(displays) {
|
||||
// Promise succeeds, but check if there are any displays actually.
|
||||
for (let i = 0; i < displays.length; i++) {
|
||||
if (displays[i].capabilities.canPresent) {
|
||||
resolve(displays[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rejectNoDisplay();
|
||||
},
|
||||
rejectNoDisplay);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter presentation mode with your set VR display
|
||||
* @param {VRDisplay} display the display to request present on
|
||||
* @param {HTMLCanvasElement} canvas
|
||||
* @return {Promise.<TResult>}
|
||||
*/
|
||||
enterVR(display, canvas) {
|
||||
this.presentedSource = canvas;
|
||||
return display.requestPresent([{
|
||||
source: canvas,
|
||||
}])
|
||||
.then(
|
||||
()=> {},
|
||||
// this could fail if:
|
||||
// 1. Display `canPresent` is false
|
||||
// 2. Canvas is invalid
|
||||
// 3. not executed via user interaction
|
||||
()=> this.__setState(State.ERROR_REQUEST_TO_PRESENT_REJECTED)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit presentation mode on display
|
||||
* @param {VRDisplay} display
|
||||
* @return {Promise.<TResult>}
|
||||
*/
|
||||
exitVR(display) {
|
||||
return display.exitPresent()
|
||||
.then(
|
||||
()=> {
|
||||
this.presentedSource = undefined;
|
||||
},
|
||||
// this could fail if:
|
||||
// 1. exit requested while not currently presenting
|
||||
()=> this.__setState(State.ERROR_EXIT_PRESENT_REJECTED)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter fullscreen mode
|
||||
* @param {HTMLCanvasElement} canvas
|
||||
* @return {boolean}
|
||||
*/
|
||||
enterFullscreen(canvas) {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.request(canvas);
|
||||
} else {
|
||||
// iOS
|
||||
this.__setState(State.PRESENTING_FULLSCREEN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit fullscreen mode
|
||||
* @return {boolean}
|
||||
*/
|
||||
exitFullscreen() {
|
||||
if (screenfull.enabled && screenfull.isFullscreen) {
|
||||
screenfull.exit();
|
||||
} else if (this.state == State.PRESENTING_FULLSCREEN) {
|
||||
this.checkDisplays();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the state of the manager
|
||||
* @param {State} state
|
||||
* @private
|
||||
*/
|
||||
__setState(state) {
|
||||
if (state != this.state) {
|
||||
this.emit('change', state, this.state);
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered on fullscreen change event
|
||||
* @param {Event} e
|
||||
* @private
|
||||
*/
|
||||
__onChangeFullscreen(e) {
|
||||
if (screenfull.isFullscreen) {
|
||||
this.__setState(State.PRESENTING_FULLSCREEN);
|
||||
} else {
|
||||
this.checkDisplays();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered on vr present change
|
||||
* @param {Event} event
|
||||
* @private
|
||||
*/
|
||||
__onVRDisplayPresentChange(event) {
|
||||
try {
|
||||
// Polyfill stores display under detail
|
||||
let display = event.display ? event.display : event.detail.display;
|
||||
if(display.isPresenting && display.getLayers()[0].source !== this.presentedSource) {
|
||||
// this means a different instance of WebVRManager has requested to present
|
||||
return;
|
||||
}
|
||||
|
||||
const isPresenting = this.defaultDisplay && this.defaultDisplay.isPresenting;
|
||||
this.__setState(isPresenting ? State.PRESENTING : State.READY_TO_PRESENT);
|
||||
} catch(err) {
|
||||
// continue regardless of error
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
3717
node_modules/webvr-ui/yarn.lock
generated
vendored
Normal file
3717
node_modules/webvr-ui/yarn.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user