navigation history works
This commit is contained in:
parent
b8a41ebce0
commit
2b480c04f5
10 changed files with 1747 additions and 55 deletions
21
dist/xrfragment.aframe.js
vendored
21
dist/xrfragment.aframe.js
vendored
|
|
@ -770,6 +770,7 @@ xrf.parseModel = function(model,url){
|
||||||
let file = xrf.getFile(url)
|
let file = xrf.getFile(url)
|
||||||
model.file = file
|
model.file = file
|
||||||
model.render = function(){}
|
model.render = function(){}
|
||||||
|
// eval embedded XR fragments
|
||||||
model.scene.traverse( (mesh) => xrf.eval.mesh(mesh,model) )
|
model.scene.traverse( (mesh) => xrf.eval.mesh(mesh,model) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -854,11 +855,17 @@ xrf.add = (object) => {
|
||||||
xrf.navigator = {}
|
xrf.navigator = {}
|
||||||
|
|
||||||
xrf.navigator.to = (url,event) => {
|
xrf.navigator.to = (url,event) => {
|
||||||
debugger
|
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
console.log("xrfragment: navigating to "+url)
|
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||||
if( xrf.model.file == file ) return resolve(xrf.model) // we're already loaded
|
console.log("xrfragment: navigating to "+url)
|
||||||
|
|
||||||
|
if( !file || xrf.model.file == file ){ // we're already loaded
|
||||||
|
document.location.hash = `#${hash}` // just update the hash
|
||||||
|
xrf.eval( url, xrf.model ) // and eval URI XR fragments
|
||||||
|
return resolve(xrf.model)
|
||||||
|
}
|
||||||
|
|
||||||
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[ext]
|
||||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||||
|
|
@ -870,7 +877,8 @@ xrf.navigator.to = (url,event) => {
|
||||||
model.file = file
|
model.file = file
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.model = model
|
xrf.model = model
|
||||||
xrf.navigator.commit( file, hash )
|
xrf.eval( url, model ) // and eval URI XR fragments
|
||||||
|
xrf.navigator.pushState( file, hash )
|
||||||
resolve(model)
|
resolve(model)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -884,7 +892,7 @@ xrf.navigator.init = () => {
|
||||||
xrf.navigator.init.inited = true
|
xrf.navigator.init.inited = true
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.navigator.commit = (file,hash) => {
|
xrf.navigator.pushState = (file,hash) => {
|
||||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||||
}
|
}
|
||||||
|
|
@ -1096,11 +1104,10 @@ xrf.frag.src = function(v, opts){
|
||||||
}
|
}
|
||||||
window.AFRAME.registerComponent('xrf', {
|
window.AFRAME.registerComponent('xrf', {
|
||||||
schema: {
|
schema: {
|
||||||
rig: {type: 'selector'}
|
|
||||||
},
|
},
|
||||||
init: function () {
|
init: function () {
|
||||||
if( !AFRAME.XRF ) this.initXRFragments()
|
if( !AFRAME.XRF ) this.initXRFragments()
|
||||||
if( typeof this.data == "string" ){
|
if( this.data ){
|
||||||
AFRAME.XRF.navigator.to(this.data)
|
AFRAME.XRF.navigator.to(this.data)
|
||||||
.then( (model) => {
|
.then( (model) => {
|
||||||
let gets = [ ...document.querySelectorAll('[xrf-get]') ]
|
let gets = [ ...document.querySelectorAll('[xrf-get]') ]
|
||||||
|
|
|
||||||
1678
dist/xrfragment.py
vendored
Normal file
1678
dist/xrfragment.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
18
dist/xrfragment.three.js
vendored
18
dist/xrfragment.three.js
vendored
|
|
@ -770,6 +770,7 @@ xrf.parseModel = function(model,url){
|
||||||
let file = xrf.getFile(url)
|
let file = xrf.getFile(url)
|
||||||
model.file = file
|
model.file = file
|
||||||
model.render = function(){}
|
model.render = function(){}
|
||||||
|
// eval embedded XR fragments
|
||||||
model.scene.traverse( (mesh) => xrf.eval.mesh(mesh,model) )
|
model.scene.traverse( (mesh) => xrf.eval.mesh(mesh,model) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -854,11 +855,17 @@ xrf.add = (object) => {
|
||||||
xrf.navigator = {}
|
xrf.navigator = {}
|
||||||
|
|
||||||
xrf.navigator.to = (url,event) => {
|
xrf.navigator.to = (url,event) => {
|
||||||
debugger
|
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
console.log("xrfragment: navigating to "+url)
|
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||||
if( xrf.model.file == file ) return resolve(xrf.model) // we're already loaded
|
console.log("xrfragment: navigating to "+url)
|
||||||
|
|
||||||
|
if( !file || xrf.model.file == file ){ // we're already loaded
|
||||||
|
document.location.hash = `#${hash}` // just update the hash
|
||||||
|
xrf.eval( url, xrf.model ) // and eval URI XR fragments
|
||||||
|
return resolve(xrf.model)
|
||||||
|
}
|
||||||
|
|
||||||
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[ext]
|
||||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||||
|
|
@ -870,7 +877,8 @@ xrf.navigator.to = (url,event) => {
|
||||||
model.file = file
|
model.file = file
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.model = model
|
xrf.model = model
|
||||||
xrf.navigator.commit( file, hash )
|
xrf.eval( url, model ) // and eval URI XR fragments
|
||||||
|
xrf.navigator.pushState( file, hash )
|
||||||
resolve(model)
|
resolve(model)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -884,7 +892,7 @@ xrf.navigator.init = () => {
|
||||||
xrf.navigator.init.inited = true
|
xrf.navigator.init.inited = true
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.navigator.commit = (file,hash) => {
|
xrf.navigator.pushState = (file,hash) => {
|
||||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,18 +15,13 @@
|
||||||
<div id="overlay" x-data="{ urls: ['#pos=0,1.6,15&rot=0,360,0'] }">
|
<div id="overlay" x-data="{ urls: ['#pos=0,1.6,15&rot=0,360,0'] }">
|
||||||
<img src="./../../assets/logo.png" class="logo"/>
|
<img src="./../../assets/logo.png" class="logo"/>
|
||||||
<input type="submit" value="load 3D asset"></input>
|
<input type="submit" value="load 3D asset"></input>
|
||||||
<input type="text" id="uri" list="urls" value="#pos=0,1.6,15&rot=0,360,0" x-on:change="document.location.hash = $('#uri').value"/>
|
<input type="text" id="uri" value="" onchange="AFRAME.XRF.navigator.to( $('#uri').value )"/>
|
||||||
<datalist id="urls" >
|
|
||||||
<template x-for="url in urls">
|
|
||||||
<option x-bind:value="url" selected></option>
|
|
||||||
</template>
|
|
||||||
</datalist>
|
|
||||||
</div>
|
</div>
|
||||||
<a class="btn-foot" id="source" target="_blank" href="https://github.com/coderofsalvation/xrfragment/blob/main/example/aframe/sandbox/index.html">sourcecode</a>
|
<a class="btn-foot" id="source" target="_blank" href="https://github.com/coderofsalvation/xrfragment/blob/main/example/aframe/sandbox/index.html">sourcecode</a>
|
||||||
<a class="btn-foot" id="model" target="_blank" href="">⬇️ model</a>
|
<a class="btn-foot" id="model" target="_blank" href="">⬇️ model</a>
|
||||||
<textarea style="display:none"></textarea>
|
<textarea style="display:none"></textarea>
|
||||||
<a-scene light="defaultLightsEnabled: false">
|
<a-scene light="defaultLightsEnabled: false">
|
||||||
<a-entity xrf id="player" >
|
<a-entity id="player" >
|
||||||
<a-entity camera position="0 1.6 15" wasd-controls id="camera"></a-entity>
|
<a-entity camera position="0 1.6 15" wasd-controls id="camera"></a-entity>
|
||||||
<a-entity id="left-hand" laser-controls="hand: left" raycaster="objects:.collidable;far:5500" oculus-touch-controls="hand: left" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor"></a-entity>
|
<a-entity id="left-hand" laser-controls="hand: left" raycaster="objects:.collidable;far:5500" oculus-touch-controls="hand: left" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor"></a-entity>
|
||||||
<a-entity id="right-hand" laser-controls="hand: right" raycaster="objects:.collidable;far:5500" oculus-touch-controls="hand: right" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor"></a-entity>
|
<a-entity id="right-hand" laser-controls="hand: right" raycaster="objects:.collidable;far:5500" oculus-touch-controls="hand: right" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor"></a-entity>
|
||||||
|
|
@ -37,28 +32,15 @@
|
||||||
</a-scene>
|
</a-scene>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { loadFile, setupConsole } from './../../assets/utils.js';
|
import { loadFile, setupConsole, setupUrlBar } from './../../assets/utils.js';
|
||||||
window.$ = (s) => document.querySelector(s)
|
window.$ = (s) => document.querySelector(s)
|
||||||
|
|
||||||
if( document.location.search.length > 2 )
|
if( document.location.search.length > 2 )
|
||||||
$('#home').setAttribute('xrf', document.location.search.substr(1) )
|
$('#home').setAttribute('xrf', document.location.search.substr(1)+document.location.hash )
|
||||||
|
|
||||||
$('a-scene').addEventListener('loaded', () => {
|
$('a-scene').addEventListener('loaded', () => {
|
||||||
setupConsole( $('textarea') )
|
setupConsole( $('textarea') )
|
||||||
|
setupUrlBar( $('input#uri') )
|
||||||
let nav = window.AFRAME.XRF.navigator
|
|
||||||
nav.to = ((to) => (url,e) => {
|
|
||||||
to(url,e)
|
|
||||||
reflectUrl()
|
|
||||||
})(nav.to)
|
|
||||||
|
|
||||||
const reflectUrl = () => $('#uri').value = document.location.search.substr(1) + document.location.hash
|
|
||||||
reflectUrl()
|
|
||||||
// update url when sandbox-url is updated
|
|
||||||
//window.addEventListener('hashchange', () => {
|
|
||||||
// window.AFRAME.XRF.eval( $('#uri').value = document.location.hash )
|
|
||||||
//})
|
|
||||||
//if( document.location.hash.length < 2 ) document.location.hash = $('#uri').value
|
|
||||||
|
|
||||||
// add look-controls at last (otherwise it'll be buggy after scene-updates)
|
// add look-controls at last (otherwise it'll be buggy after scene-updates)
|
||||||
$('[camera]').setAttribute("look-controls","")
|
$('[camera]').setAttribute("look-controls","")
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ input[type="submit"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
#overlay > #uri {
|
#overlay > #uri {
|
||||||
|
display:none;
|
||||||
height: 29px;
|
height: 29px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -50,3 +50,21 @@ export function setupConsole(el){
|
||||||
$console.scrollTop = $console.scrollHeight;
|
$console.scrollTop = $console.scrollHeight;
|
||||||
})(console.log.bind(console))
|
})(console.log.bind(console))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setupUrlBar(el){
|
||||||
|
|
||||||
|
var isIframe = (window === window.parent || window.opener) ? false : true;
|
||||||
|
if( isIframe ){
|
||||||
|
// show internal URL bar to test XR fragments interactively
|
||||||
|
el.style.display = 'block'
|
||||||
|
let nav = window.AFRAME.XRF.navigator
|
||||||
|
|
||||||
|
AFRAME.XRF.navigator.to = ((to) => (url,e) => {
|
||||||
|
to(url,e)
|
||||||
|
reflectUrl(url)
|
||||||
|
})(AFRAME.XRF.navigator.to)
|
||||||
|
|
||||||
|
const reflectUrl = (url) => el.value = url || document.location.search.substr(1) + document.location.hash
|
||||||
|
reflectUrl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,7 @@
|
||||||
<div id="overlay" x-data="{ urls: ['#pos=0,1.6,15','#pos=0,1.6,15&rot=0,360,0'] }">
|
<div id="overlay" x-data="{ urls: ['#pos=0,1.6,15','#pos=0,1.6,15&rot=0,360,0'] }">
|
||||||
<img src="./../../assets/logo.png" class="logo"/>
|
<img src="./../../assets/logo.png" class="logo"/>
|
||||||
<input type="submit" value="load 3D asset"></input>
|
<input type="submit" value="load 3D asset"></input>
|
||||||
<input type="text" id="uri" list="urls" value="#pos=0,1.6,15&rot=0,360,0" x-on:change="document.location.hash = $('#uri').value"/>
|
<input type="text" id="uri" value="" onchange="AFRAME.XRF.navigator.to( $('#uri').value )"/>
|
||||||
<datalist id="urls" >
|
|
||||||
<template x-for="url in urls">
|
|
||||||
<option x-bind:value="url" selected></option>
|
|
||||||
</template>
|
|
||||||
</datalist>
|
|
||||||
</div>
|
</div>
|
||||||
<a class="btn-foot" id="source" target="_blank" href="https://github.com/coderofsalvation/xrfragment/blob/main/example/threejs/sandbox/index.html#L92-L112">sourcecode</a>
|
<a class="btn-foot" id="source" target="_blank" href="https://github.com/coderofsalvation/xrfragment/blob/main/example/threejs/sandbox/index.html#L92-L112">sourcecode</a>
|
||||||
<a class="btn-foot" id="model" target="_blank" href="">⬇️ model</a>
|
<a class="btn-foot" id="model" target="_blank" href="">⬇️ model</a>
|
||||||
|
|
@ -40,7 +35,7 @@
|
||||||
|
|
||||||
import xrfragment from './../../../dist/xrfragment.three.js';
|
import xrfragment from './../../../dist/xrfragment.three.js';
|
||||||
|
|
||||||
import { loadFile, setupConsole } from './../../assets/utils.js';
|
import { loadFile, setupConsole, setupUrlBar } from './../../assets/utils.js';
|
||||||
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
|
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
|
||||||
import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js';
|
import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js';
|
||||||
import { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js';
|
import { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js';
|
||||||
|
|
@ -98,11 +93,6 @@
|
||||||
loaders: { gltf: GLTFLoader, fbx: FBXLoader }, // which 3D assets (extensions) to check for XR fragments?
|
loaders: { gltf: GLTFLoader, fbx: FBXLoader }, // which 3D assets (extensions) to check for XR fragments?
|
||||||
})
|
})
|
||||||
|
|
||||||
// init navigator url
|
|
||||||
window.addEventListener('hashchange', () => {
|
|
||||||
window.XRF.eval( $('#uri').value = document.location.hash )
|
|
||||||
})
|
|
||||||
if( document.location.hash.length < 2 ) document.location.hash = $('#uri').value
|
|
||||||
|
|
||||||
// optional: react/extend/hook into XR fragment
|
// optional: react/extend/hook into XR fragment
|
||||||
XRF.env = (xrf,v,opts) => {
|
XRF.env = (xrf,v,opts) => {
|
||||||
|
|
@ -126,7 +116,7 @@
|
||||||
|
|
||||||
window.XRF = XRF // expose to form
|
window.XRF = XRF // expose to form
|
||||||
|
|
||||||
let file = document.location.search.length > 2 ? document.location.search.substr(1) : './../../assets/example3.gltf'
|
let file = document.location.search.length > 2 ? document.location.search.substr(1) + document.location.hash : './../../assets/example3.gltf#pos=0,1,15'
|
||||||
$('#model').setAttribute("href","./../../asset/"+file)
|
$('#model').setAttribute("href","./../../asset/"+file)
|
||||||
XRF.navigator.to( file )
|
XRF.navigator.to( file )
|
||||||
|
|
||||||
|
|
@ -176,6 +166,7 @@
|
||||||
|
|
||||||
|
|
||||||
setupConsole()
|
setupConsole()
|
||||||
|
setupUrlBar( $('input#uri') )
|
||||||
|
|
||||||
// GUI
|
// GUI
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
window.AFRAME.registerComponent('xrf', {
|
window.AFRAME.registerComponent('xrf', {
|
||||||
schema: {
|
schema: {
|
||||||
rig: {type: 'selector'}
|
|
||||||
},
|
},
|
||||||
init: function () {
|
init: function () {
|
||||||
if( !AFRAME.XRF ) this.initXRFragments()
|
if( !AFRAME.XRF ) this.initXRFragments()
|
||||||
if( typeof this.data == "string" ){
|
if( this.data ){
|
||||||
AFRAME.XRF.navigator.to(this.data)
|
AFRAME.XRF.navigator.to(this.data)
|
||||||
.then( (model) => {
|
.then( (model) => {
|
||||||
let gets = [ ...document.querySelectorAll('[xrf-get]') ]
|
let gets = [ ...document.querySelectorAll('[xrf-get]') ]
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ xrf.parseModel = function(model,url){
|
||||||
let file = xrf.getFile(url)
|
let file = xrf.getFile(url)
|
||||||
model.file = file
|
model.file = file
|
||||||
model.render = function(){}
|
model.render = function(){}
|
||||||
|
// eval embedded XR fragments
|
||||||
model.scene.traverse( (mesh) => xrf.eval.mesh(mesh,model) )
|
model.scene.traverse( (mesh) => xrf.eval.mesh(mesh,model) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
xrf.navigator = {}
|
xrf.navigator = {}
|
||||||
|
|
||||||
xrf.navigator.to = (url,event) => {
|
xrf.navigator.to = (url,event) => {
|
||||||
debugger
|
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
console.log("xrfragment: navigating to "+url)
|
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||||
if( xrf.model.file == file ) return resolve(xrf.model) // we're already loaded
|
console.log("xrfragment: navigating to "+url)
|
||||||
|
|
||||||
|
if( !file || xrf.model.file == file ){ // we're already loaded
|
||||||
|
document.location.hash = `#${hash}` // just update the hash
|
||||||
|
xrf.eval( url, xrf.model ) // and eval URI XR fragments
|
||||||
|
return resolve(xrf.model)
|
||||||
|
}
|
||||||
|
|
||||||
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[ext]
|
||||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||||
|
|
@ -17,7 +23,8 @@ xrf.navigator.to = (url,event) => {
|
||||||
model.file = file
|
model.file = file
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.model = model
|
xrf.model = model
|
||||||
xrf.navigator.commit( file, hash )
|
xrf.eval( url, model ) // and eval URI XR fragments
|
||||||
|
xrf.navigator.pushState( file, hash )
|
||||||
resolve(model)
|
resolve(model)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -31,7 +38,7 @@ xrf.navigator.init = () => {
|
||||||
xrf.navigator.init.inited = true
|
xrf.navigator.init.inited = true
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.navigator.commit = (file,hash) => {
|
xrf.navigator.pushState = (file,hash) => {
|
||||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue