xrfragment/src/3rd/js/three/navigator.js

89 lines
3.3 KiB
JavaScript
Raw Normal View History

2023-05-17 21:31:28 +02:00
xrf.navigator = {}
2023-07-04 17:15:23 +02:00
xrf.navigator.to = (url,flags,loader,data) => {
2023-05-18 17:11:11 +02:00
if( !url ) throw 'xrf.navigator.to(..) no url given'
let hashbus = xrf.hashbus
2023-11-08 18:28:18 +01:00
xrf.emit('navigate', {url,loader,data})
2023-05-17 21:31:28 +02:00
return new Promise( (resolve,reject) => {
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
2023-10-15 13:35:54 +02:00
if( !file || (!data && xrf.model.file == file) ){ // we're already loaded
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
xrf.navigator.updateHash(hash)
2023-05-18 17:11:11 +02:00
return resolve(xrf.model)
}
2023-05-17 21:31:28 +02:00
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
2023-07-04 17:15:23 +02:00
if( !loader ){
const Loader = xrf.loaders[ext]
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
loader = loader || new Loader().setPath( dir )
}
2023-05-17 21:31:28 +02:00
// force relative path
if( dir ) dir = dir[0] == '.' ? dir : `.${dir}`
2023-07-05 16:43:07 +02:00
url = url.replace(dir,"")
2023-07-04 17:15:23 +02:00
loader = loader || new Loader().setPath( dir )
const onLoad = (model) => {
xrf.reset() // clear xrf objects from scene
2023-05-18 12:39:47 +02:00
model.file = file
// only change url when loading *another* file
if( xrf.model ) xrf.navigator.pushState( `${dir}${file}`, hash )
2023-05-17 21:31:28 +02:00
xrf.model = model
// spec: 1. generate the XRWG
xrf.XRWG.generate({model,scene:model.scene})
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
2023-10-27 16:55:48 +02:00
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
2023-10-12 17:04:46 +02:00
// spec: 2. init metadata
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
2023-11-29 16:45:21 +01:00
let frag = hashbus.pub( url, model) // and eval URI XR fragments
hashbus.pub.XRWG({model,scene:model.scene,frag})
xrf.add( model.scene )
xrf.navigator.updateHash(hash)
2023-11-08 18:28:18 +01:00
xrf.emit('navigateLoaded',{url,model})
2023-05-17 21:31:28 +02:00
resolve(model)
2023-07-04 17:15:23 +02:00
}
if( data ) loader.parse(data, "", onLoad )
else loader.load(url, onLoad )
2023-05-17 21:31:28 +02:00
})
}
xrf.navigator.init = () => {
if( xrf.navigator.init.inited ) return
2023-10-12 17:04:46 +02:00
2023-05-17 21:31:28 +02:00
window.addEventListener('popstate', function (event){
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
2023-05-17 21:31:28 +02:00
})
2023-10-12 17:04:46 +02:00
window.addEventListener('hashchange', function (e){
xrf.emit('hash', {hash: document.location.hash })
})
// this allows selectionlines to be updated according to the camera (renderloop)
xrf.focusLine = new xrf.THREE.Group()
xrf.focusLine.material = new xrf.THREE.LineDashedMaterial({color:0xFF00FF,linewidth:3, scale: 1, dashSize: 0.2, gapSize: 0.1,opacity:0.3, transparent:true})
xrf.focusLine.isXRF = true
xrf.focusLine.position.set(0,0,-0.5);
xrf.focusLine.points = []
xrf.focusLine.lines = []
xrf.camera.add(xrf.focusLine)
2023-05-17 21:31:28 +02:00
xrf.navigator.init.inited = true
}
xrf.navigator.updateHash = (hash,opts) => {
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
2023-06-22 13:59:17 +02:00
console.log(`URL: ${document.location.search.substr(1)}#${hash}`)
document.location.hash = hash
xrf.emit('hash', {...opts, hash: `#${hash}` })
}
2023-05-18 17:11:11 +02:00
xrf.navigator.pushState = (file,hash) => {
if( file == document.location.search.substr(1) ) return // page is in its default state
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
xrf.emit('pushState', {file, hash} )
2023-05-17 21:31:28 +02:00
}