| asset | added icons + docs | |
| example1.xml | 🔧 master: work in progress [might break] | |
| example2.xml | 🔧 master: work in progress [might break] | |
| janus-script-dialog.js | 🔧 master: work in progress [might break] | |
| janus-script-dialog.webp | 📃 master: update documentation | |
| LICENSE.txt | added license | |
| README.md | 🔧 master: work in progress [might break] | |
Dialogs for JanusXR
DEMO
Launch the examples straight into any JML browser (like janusweb):
What is it?
- easy reactive dialogs in JML
- naive markdown support
- hand-tracking support (great for AR)
- infinite scaleable AR-menu (via URLs)
- template variables
- theme-able
- dialog can intialize/watch objects and updates the dialog when keyvalues change
- redirects
window.alert(...)to immersive dialog
What is janusXR? It's an open, user-operated immersive web layer, open-sourced by the JanusVR company, that seamlessly lives within websites, even 12 years later thanks to janusweb. It provides a highly viable and easy-to-adopt ecosystem of portals, enabling immersive experiences that challenge the traditional app store paradigm. Get started with this guide.
<fireboxroom>
<assets>
<assetscript src="janus-script-jjq.js"/>
<assetscript src="janus-script-dialog.js"/>
<assetobject src="asset/button.glb" id="button"/>
<assetsound src="asset/button.click.mp3" id="button-click"/>
<assetsound src="asset/button.hover.mp3" id="button-hover"/>
</assets>
<room selfavatar="false" showavatar="false" skybox="false" walk_speed="0.8">
<dialog content_id="menu1" pos="0 1.3 0.4" rotation="0 35 0" js_id="mydialog"/>
<object js_id="menu1" watch="foo,bar" visible="false">
<paragraph width="300px" height="200px" lighting="false">
# example1.xml
Hello **world** was clicked ${room.foo.clicks = room.foo.clicks || 0} times
> this is markdown btw
</paragraph>
<button pos="-0.33 0.98 0.21" text="hello" onclick="room.foo.clicks++"/>
<button pos="0.33 0.98 0.21" text="alert()" onclick="alert('hello world')"/>
<button pos="-0.33 0.69 0.21" text="example2.xml" onclick="room.openLink('example2')"/>
<link url="example2.xml" js_id="example2" auto_load="true" scale="0 0 0"/>
</object>
</room>
</fireboxroom>
There's various things going on above:
- a dialog (re)uses content defined elsewhere (
menu1) - objects
room.fooandroom.barare being watched by the dialog (watch="foo,bar") - calling
window.alert('hello world')will trigger a dialog in front of the user
Attributes
NOTE:
<paragraph>are used for panels, since JML allows inline content for these elements. Alsofontscaleis important to set for each button, to keep the implementation KiSS.
| tag | attribute | info |
|---|---|---|
<dialog> |
content_id="string" |
which js_id of an <object> to use as content |
<dialog> |
pos="0 0 0" |
where to position your dialog |
<dialog> |
billboard="false" |
always face user or not warning: >1 transparent dialogs might tank your fps |
<dialog> |
backportal="false" |
hide backportals (desirable in AR-mode). use <button onclick=" janus.navigateBack()" text="back"/> if true |
<dialog> |
debug="false" |
show theme in browserconsole |
<dialog> |
reroute="true" |
reroute window.alert to <dialog> |
<dialog> |
theme_default="light" |
set default theme |
<object> |
watch="" |
(commaseparated) objects to watch for changes.watch="a,b" initializes/watches objects room.a and room.b |
<object> |
invert="true" |
inverts colors (useful for icon <object> inside <button> e.g.) |
<button> |
lighting"="false" |
|
<button> |
use="button" |
specify model to render behind text (default expects <assetobject src="..." id="button"/>) |
<button> |
text="my button" |
label of the text |
<button> |
locked="true" |
|
<button> |
scale="1 1 1" |
|
<button> |
scale_back="1 1 1" |
|
<button> |
fontscale="0.6" |
|
<button> |
col="0 0 0" |
|
<button> |
col_text="1 1 1" |
|
<paragraph> |
width="300px" |
set the height of markdown/html panel |
<paragraph> |
height="200px" |
set the width of markdown/html panel |
Events:
| event | example |
|---|---|
dialog_button_click |
room.addEventListener("dialog_button_click", (e) => console.log(e.text) ) |
dialog_button_hover |
room.addEventListener("dialog_button_hover", (e) => console.log(e.text) ) |
dialog_theme_init |
room.addEventListener("dialog_theme_init", (e) => console.log("theme init") ) |
dialog_theme_apply |
room.addEventListener("dialog_theme_init", (e) => console.log("theme apply") ) |
dialog_content_remove |
room.addEventListener("dialog_content_remove", (e) => console.log("remove") ) |
dialog_content_render |
room.addEventListener("dialog_content_render", (e) => console.log("render") ) |
dialog_paragraph_render |
room.addEventListener("dialog_paragraph_render", (e) => console.log("render") ) |
Examples
room.theme.current = "light" // change theme (included: "dark" and "light")
$('mydialog').render('menu2') // replaces the dialog's content with different js_id
alert("hello") // triggers popup
// bit more advanced popup
alert("OK",{timeout:1000,header:"status"})
Icons
example2.xml shows how to use icons:
<button pos="-0.56 2.09 0.21" use="icon" onclick="janus.navigateBack()">
<object id="icon-arrow-left" invert="true" lighting="false" col="1 1 1" pos="0.002 0 0.01" scale="1.8 1.8 1.8"/>
</button>
This technique works for all icons:
- add a button with custom backgroundobject (
use="icon"e.g.) - add the asset of that backgroundobject
<assetobject src="asset/button.icon.glb" id="icon"/>e.g.)
for the icon/arrow:
- download an icon
.svgfrom css.gg (asset/icon.arrow-left.glb e.g.) - blender: import
.svg - blender: convert to Mesh (rightclick in non-edit mode)
- blender: export as glb (asset/icon.back.glb e.g.)
- add asset (
<assetobject src="asset/icon.arrow-left.glb" id="icon-arrow-left"/>e.g.)
Themes
Basically include a script like below
NOTE: please check the light/dark theme in the sourcecode as a reference
room.addEventListener('dialog_theme_init', function(){
room.theme.current = "mytheme" // set my current theme as default
room.theme.mytheme = {
css: (opts) => `
/* css for <paragraph> goes here */
`,
jml: {
"*": { // this applies to all JML elements
lighting: "false"
},
text: { // or just <text> element e.g.
col: "1 0 1"
}
},
custom: (opts) => {
// here you can set things in batch via jjq selectors
$$('text', opts.db).set('col', opts.invert ? '1 0 1' : '0 1 0')
$$('object', opts.db).set('lighting', 'false')
$$('object', opts.db).set('transparent','false')
}
}
},
Notes:
- tested with janusweb 1.5.56
Usage
// TODO
commandline:
$ cd myroom
$ wget '...'