91 lines
3.5 KiB
JavaScript
91 lines
3.5 KiB
JavaScript
AFRAME.registerComponent('window', {
|
|
schema:{
|
|
title: {type:'string',"default":"title"},
|
|
width: {type:'string'}, // wrap
|
|
height: {type:'string',"default":'260px'},
|
|
uid: {type:'string'},
|
|
attach: {type:'selector'},
|
|
dom: {type:'selector'},
|
|
max: {type:'boolean',"default":false},
|
|
min: {type:'boolean',"default":false},
|
|
x: {type:'string',"default":"center"},
|
|
y: {type:'string',"default":"center"},
|
|
"class": {type:'array',"default":[]},
|
|
},
|
|
|
|
dependencies:{
|
|
dom: "com/dom.js",
|
|
winboxjs: "https://unpkg.com/winbox@0.2.82/dist/winbox.bundle.min.js", // deadsimple windows: https://nextapps-de.github.io/winbox
|
|
//winboxcss: "https://unpkg.com/winbox@0.2.82/dist/css/winbox.min.css", // main theme
|
|
},
|
|
|
|
init: function(){
|
|
setTimeout( () => this.setupWindow(), 10 ) // init after other components
|
|
},
|
|
|
|
setupWindow: async function(){
|
|
await AFRAME.utils.require(this.dependencies)
|
|
if( !this.el.dom ) return console.error('window element requires dom-component as dependency')
|
|
|
|
this.el.dom.style.display = 'none'
|
|
let winbox = this.el.winbox = new WinBox( this.data.title, {
|
|
class: this.data.class,
|
|
height:this.data.height,
|
|
width:this.data.width,
|
|
x: this.data.x,
|
|
y: this.data.y,
|
|
id: this.data.uid || String(Math.random()).substr(4), // important hint for html-mesh
|
|
root: this.data.attach || document.body,
|
|
mount: this.data.dom,
|
|
max: this.data.max,
|
|
min: this.data.min,
|
|
onresize: () => this.el.emit('window.onresize',{}),
|
|
onmaximize: () => this.el.emit('window.onmaximize',{}),
|
|
oncreate: (e) => {
|
|
this.el.emit('window.oncreate',{})
|
|
// resize after the dom content has been rendered & updated
|
|
setTimeout( () => {
|
|
if( !this.data.max ) winbox.resize( this.el.dom.offsetWidth+'px', this.el.dom.offsetHeight+'px' )
|
|
// hint grabbable's obb-collider to track the window-object
|
|
this.el.components['obb-collider'].data.trackedObject3D = 'components.html.el.object3D.children.0'
|
|
this.el.components['obb-collider'].update()
|
|
},1000)
|
|
},
|
|
onclose: () => {
|
|
let e = {halt:false}
|
|
this.el.emit('window.onclose',e)
|
|
if( e.halt ) return true
|
|
this.data.dom.style.display = 'none';
|
|
if( this.el.parentNode ) this.el.remove() //parentElement.remove( this.el )
|
|
this.data.dom.parentElement.remove()
|
|
return false
|
|
},
|
|
});
|
|
this.data.dom.style.display = '' // show
|
|
|
|
this.el.setAttribute("grabbable","")
|
|
|
|
if( this.el.object3D.position.x == 0 &&
|
|
this.el.object3D.position.y == 0 &&
|
|
this.el.object3D.position.z == 0 ){ // position next to previous window
|
|
var els = [...document.querySelectorAll('[window]')]
|
|
if( els.length < 2 ) return
|
|
let current = els[ els.length-1 ]
|
|
let last = els[ els.length-2 ]
|
|
AFRAME.utils.positionObjectNextToNeighbor( current.object3D , last.object3D, 0.02 )
|
|
}
|
|
},
|
|
|
|
show: function(state){
|
|
this.el.dom.closest('.winbox').style.display = state ? '' : 'none'
|
|
}
|
|
})
|
|
|
|
AFRAME.utils.positionObjectNextToNeighbor = function positionObjectNextToNeighbor(object, lastNeighbor = null, margin ){
|
|
// *FIXME* this could be more sophisticated :)
|
|
object.position.x = lastNeighbor.position.x + margin
|
|
object.position.y = lastNeighbor.position.y - margin
|
|
object.position.z = lastNeighbor.position.z + margin
|
|
|
|
}
|