Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/coderofsalvation/aframe-verse
deadsimple immersive navigation: a single-player-verse component
https://github.com/coderofsalvation/aframe-verse
aframe augmented-reality navigation oculus-quest virtual-reality vr webxr
Last synced: 2 months ago
JSON representation
deadsimple immersive navigation: a single-player-verse component
- Host: GitHub
- URL: https://github.com/coderofsalvation/aframe-verse
- Owner: coderofsalvation
- License: gpl-3.0
- Created: 2022-11-01T12:49:37.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2023-05-22T08:07:35.000Z (over 1 year ago)
- Last Synced: 2023-05-22T09:24:58.104Z (over 1 year ago)
- Topics: aframe, augmented-reality, navigation, oculus-quest, virtual-reality, vr, webxr
- Language: JavaScript
- Homepage: https://coderofsalvation.github.io/aframe-verse/apps
- Size: 3.71 MB
- Stars: 13
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
> LATEST NEWS: for an AFRAME & file-format-agnostic version see [the XR Fragments standard instead](https://coderofsalvation.github.io/xrfragment/#XR%20Fragments)
## AFRAME-verse, deadsimple immersive navigation
![](.img/demo.gif)
A single-player-verse component for [AFRAME](https://aframe.io):
### TRY THE [ONLINE DEMO](https://coderofsalvation.github.io/aframe-verse/apps/)
* ❤️ easily teleport between aframe apps & aframe-verse clusters
* ❤️ does not exit immersive-mode when navigating to different aframe experiences
* ❤️ standalone & serverless: no servers (NAF/signaling) needed
* ❤️ HTML-first: even runs from wordpress, no ninja javascript-skills needed
* ❤️ #networkless #decentralized #noblockchain #permissionless-first #federatedpullrequests> Similar to a **WEB**ring, you can easily create **DOM**rings and **VERSE**rings with this component, that can be **Zuckerburgered** by yourself (or friends).
Usage
```html
```
Recursive description of a verse (`aframe-verse.json`):
```json
{
"schema":"aframe-verse/0.1",
"destinations":[
{"url":"./index.html"}, // immersive navigation
{"url":"./app2.html" }, //
{"url":"https://coderofsalvation.gitlab.io/aframe-urwhatuthink/experience.html", "title":"Leon Du Star - URWHATUTHINK", "scripts":true},
{"url":"https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/",
"author":"Fabien Benetou",
"newtab": true // opens in new tab (does not contain aframe-verse component)
}
],
"verses":[ // import trusted destinations
{"url":"https://coderofsalvation.github.io/aframe-verse-leondustar/aframe-verse.json", "scripts":true}
]
}
```
Click here for properties
| property | type | info |
|------------|------|------|
| debug | bool (false) | shows info in the browserconsole |
| register | string | location of aframe-verse.json destinations |
| hrefEvents | stringarray (click, collide) | events which trigger teleport to href |
| fade | integer (100) | amount (in ms) of fade-in fade-out time |
| fadeColor | string ('black') | (hex)color(name) for fading |
Click here for events
| component | property | promise | info |
|--------------|--------------|---------|------------------------------------|
| aframe-verse | registerJSON | no |fires when loading aframe-verse JSON file(s) |
| href | beforeNavigate | yes |fires before navigation fadeout |
| href | navigate | yes |fires after navigation fadeout |
| href | loadHTML | yes |fires before inserting new DOM content |
| href | loaded | yes |fires after all DOM content is loaded ('domready' e.g.)|> See chapter `Customizing (with code)` > `Customizing navigation Further` for flowcontrol using promises.
How it works
![](.img/flow.jpg)
A visitor in an **aframe-verse** just teleports to other destinations and clusters ("*beam me up scotty!*").
`aframe-verse.json` is just a telephone-book of destinations.> When a visitor surfs to a cluster-client ([index.html](apps/index.html)), it loads all components, which other linked experiences use.
How does this works in large?
The concept above is an answer to the fact that each tile-based 'metaverse' will always turn into some kind of **hypercentralized** client-project.
Instead, a visitor in the **aframe-verse** just teleports to other destinations and clusters.
When the visitor surfs to a cluster-client ([index.html](apps/index.html)), it basically loads all components, which other linked experiences use.
This is a security-limitation and a performance-feature, because this:
* makes traveling between experiences (within a cluster) very fluid and fast.
* it creates a decentralized incentive between developer(s) to:
* collaborate on a seamless & secure end-visitor cluster-client ([index.html](apps/index.html))
* consistent UX because of:
* shared components
* shared global objects: wearables, UI, AR/VR controller-support e.g.
> As an exception to the rule, the developer(s) (YOU) of a cluster-client ([index.html](apps/index.html)) can load remote (trusted) components/scripts, which is demonstrated by [aframe-verse-component-scripts](https://github.com/coderofsalvation/aframe-verse-component-scripts).
Worstcase, a destination can be loaded in a new tab (`newtab:true` which exits immersive navigation ), which then basically becomes the new cluster.
Federated HTML-first verse-clusters
> aframe-verse describes a verse using the lowest common denominator between Aframe authors (=a webdirectory)
This could be a github-repo, or linuxserver where:
* the **maintainer(s)** maintain a pool of trusted aframe apps (& components)
* the **maintainer(s)** allow DOM-sharing (a DOM-ring) between eachothers aframe-apps
* the **maintainer(s)** agree on shared garbage collection> Ideally, the maintainers need to approve new (website-specific) scripts/components, and include them in [index.html](apps/index.html) when a new app arrives thru merge requests.
#### But..but..what about privacy & security?
This is all up to the maintainers of a verse, just think of it as running a shared website & linksharing.
For more info [read this](https://github.com/coderofsalvation/aframe-verse/issues/1)
Project scope
Out of the box, this component is good enough for seamlessly navigating between **simple read-only** aframe experiences (galleries, portfolios, vr movies, viewing scenes e.g.).
A monoverse is the opposite of a 'metaverse'-concept (in which multiplayer-communication is fundamental).
Therefore, the following is out of scope, but can still be used to progressively enhance an `aframe-verse`:* multiplayer: see the (way more complex) [NAF approach](https://github.com/networked-aframe) which requires you to run your own server.
* hardened security/privacy: introduce activitypub-layer, p2p webrtc like yjs
How to add experiences?
> Just check [index.html](apps/index.html) and [app2.html](apps/app2.html), Basically:
* put your aframe apps in `apps/*` (they should have an `aframe-verse`-attribute set somewhere)
* add `href`-attributes to clickable items (see example)
* use `href="./afile.html"` to teleport to relative files
* whitelist `href="https://..."`-links by including them in `aframe-verse.json` (see browserconsole for errors)
* use `href="/"` to guide the visitor back to the original cluster
How to add components?
Typically these are included in the cluster-client [index.html](apps/index.html).
#### What if other apps require certain components/scripts?As an exception to the rule, you can load remote (trusted) components/scripts, which is demonstrated by [aframe-verse-component-scripts](https://github.com/coderofsalvation/aframe-verse-component-scripts).
Customizing (with code)
> Rule of thumb: load (or extend loading) components in the cluster-client ([index.html](apps/index.html))
Extending navigation interactions
By defining `hrefEvents`, you can trigger navigation for other events too:
```html
<... aframe-verse="register: /yourverse.json; hrefEvents: click, mouseenter, collide, foobar">
```
> Profit! Now navigation is triggered to `show.html` whenever it is clicked, mousehovered or colliding with another object
calling `$('[aframe-verse] [href]').emit('foobar', {})` would trigger navigation too
Customizing navigation further
You can control navigation-events by creating a custom component:
```
// use like:AFRAME.registerComponent('navigate', {
init: function(){
console.log("initing navigation")
this.el.addEventListener('beforeNavigate', (e) => this.beforeNavigate(e) )
this.el.addEventListener('navigate', (e) => this.navigate(e) )
this.el.addEventListener('loadHTML', (e) => this.loadHTML(e) )
this.el.addEventListener('registerJSON', (e) => this.registerJSON(e) )
},
beforeNavigate(e){
// let promise = e.detail.promise()
console.log("about to navigate to: "+e.detail.destination.url)
// promise.resolve()
// promise.reject("not going to happen")
},
navigate(e){
// let promise = e.detail.promise()
console.log("navigating to: "+e.detail.destination.url)
// promise.resolve()
// promise.reject("not going to happen")
},
loadHTML(e){
let newdom = e.detail.dom.querySelector("[aframe-verse]")
// let promise = e.detail.promise()
console.log("loading html")
// promise.resolve()
// promise.reject("not going to happen")
},
registerJSON(e){
let json = e.detail.json
/* example: skip non-immersive navigation links */
// json.destinations = json.destinations.filter( (d) => d.newtab ? null : d )
/* example: launch external verses in a new tab (so its components get loaded too) */
// json.destinations.map( (d) => d.url.match(/index\.html$/) ? d.newtab = true : null )
}
})
```> This is the place to show a consent popup e.g. (most trusted experiences can do fine without that in the beginning).
Connecting, Nesting & Securing verse-clusters
![](.img/yodawg.jpg)
For navigation, you can add external verses to the `.verses`-array in `aframe-verse.json`, that's all!
Optionally, you can secure the import-behaviour further using the `registerJSON`-event as shown above in 'Customizing navigation further'.
Fadetime & nesting verses
You can have multiple persisting verses at the same time.
Usecases for this are: a menu system, mini-games, inventory or a teleporting-maze e.g.:```html
...
...```
> NOTE: for heavy scenes you can set `fade: 4000` (4seconds fade) e.g.
Publish, selfhost & connect your verse (for free)
3 ways of hosting:
GITHUB / GITLAB
* click the fork-button on [github](https://github.com/coderofsalvation/aframe-verse) or [gitlab](https://gitlab.com/coderofsalvation/aframe-verse)
* rename the repository to `aframe-verse-*` (aframe-verse-myorganisation e.g.) for easy discoverability
* github: go to settings-tab > enable github pages (use the main-branch)
* profit! your verse can now be accessed thru
* github: `https://yourusername.github.io/aframe-verse-myorganisation/apps`
* gitlab: `https://yourusername.gitlab.io/aframe-verse-myorganisation/apps`
GLITCH
* [REMIX this glitch](https://glitch.com/edit/#!/remix/aframe-verse)
* rename the project to `aframe-verse-*` (aframe-verse-myorganisation e.g.) for easy discoverability
* your verse can now be accessed thru `https://aframe-verse-myorganisation.glitch.me/apps/`
SELFHOSTING (redbean/wordpress/apache e.g.)
* [download zip](https://github.com/coderofsalvation/aframe-verse/archive/refs/heads/main.zip) and unpack it in your apache/worpress dir e.g.
> Later: please connect your verse to this repo, by submitting a PR or mentioning your json-URL in an issue. That way, future verses (forks) will automatically include your verse too.
Scope / Contributing
All feedback,bugfixes are very welcome ❤️
Other things (features/privacy/security/consent-stuff e.g.) should be published as separate components (see the `navigate` custom-component example in the [aframe-verse README.md](https://github.com/coderofsalvation/aframe-verse) in the `Customizing (with code) > Customizing navigation further` section.
> Please publish any useful components under reponame `aframe-verse-component-mycomponent` for discoverability.
As a startingpoint for extending, you can simply fork the [scripts-component](https://github.com/coderofsalvation/aframe-verse-component-scripts) as well