add window.js + autolaunch + update isoterminal scale
This commit is contained in:
parent
07564881fd
commit
8b978848ff
|
@ -95,7 +95,7 @@ AFRAME.registerComponent('dom',{
|
|||
|
||||
assignUniqueID: function(){
|
||||
// assign unique app id so it's easy to reference (by html-mesh component e.g.)
|
||||
if( !this.el.uid ) this.el.uid = '_'+String(Math.random()).substr(10)
|
||||
if( !this.el.uid ) this.el.uid = this.el.dom.id = '_'+String(Math.random()).substr(10)
|
||||
return this
|
||||
},
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ AFRAME.registerComponent('isoterminal', {
|
|||
},
|
||||
|
||||
requires:{
|
||||
'window': "com/window.js",
|
||||
html: "https://unpkg.com/aframe-htmlmesh@2.1.0/build/aframe-html.js", // html to AFRAME
|
||||
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", //
|
||||
|
@ -21,11 +22,11 @@ AFRAME.registerComponent('isoterminal', {
|
|||
},
|
||||
|
||||
dom: {
|
||||
scale: 3,
|
||||
scale: 0.7,
|
||||
events: ['click','keydown'],
|
||||
html: (me) => `<div class="isoterminal">
|
||||
<div style="white-space: pre; font: 14px monospace; line-height: 14px"></div>
|
||||
<canvas/>
|
||||
<canvas></canvas>
|
||||
</div>`,
|
||||
|
||||
css: (me) => `.isoterminal{
|
||||
|
@ -44,48 +45,6 @@ AFRAME.registerComponent('isoterminal', {
|
|||
}`
|
||||
},
|
||||
|
||||
createTerminal: async function(instance){
|
||||
const dom = instance.dom
|
||||
//this.el.object3D.visible = true
|
||||
|
||||
const term = this.term = new Terminal({
|
||||
allowTransparency: this.data.transparent,
|
||||
cursorBlink: true,
|
||||
disableStdin: false,
|
||||
rows: this.data.rows,
|
||||
cols: this.data.cols,
|
||||
fontSize: 16
|
||||
})
|
||||
|
||||
term.open(dom)
|
||||
this.canvas = dom.querySelector('.xterm-text-layer')
|
||||
this.canvas.id = 'terminal-' + instance.uid
|
||||
this.canvasContext = this.canvas.getContext('2d')
|
||||
|
||||
this.cursorCanvas = dom.querySelector('.xterm-cursor-layer')
|
||||
|
||||
//this.el.setAttribute('material', `transparent: ${this.data.transparent?'true':'false'}; src: #${this.canvas.id}` )
|
||||
|
||||
term.on('refresh', () => {
|
||||
console.log("refresh")
|
||||
})
|
||||
|
||||
term.on('data', (data) => {
|
||||
console.log(data)
|
||||
this.el.emit('xterm-data', data)
|
||||
})
|
||||
|
||||
this.el.addEventListener('click', () => {
|
||||
term.focus()
|
||||
})
|
||||
|
||||
const message = 'Hello from \x1B[1;3;31mWebVR\x1B[0m !\r\n$ '
|
||||
term.write(message)
|
||||
|
||||
this.runISO()
|
||||
return {width: this.canvas.width, height: this.canvas.height }
|
||||
},
|
||||
|
||||
runISO: function(dom){
|
||||
var emulator = window.emulator = new V86({
|
||||
wasm_path: "com/isoterminal/v86.wasm",
|
||||
|
@ -102,12 +61,12 @@ AFRAME.registerComponent('isoterminal', {
|
|||
cdrom: {
|
||||
url: this.data.iso,
|
||||
},
|
||||
network_relay_url: "<UNUSED>",
|
||||
cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_free=on",
|
||||
//bzimage:{
|
||||
// url: "com/isoterminal/images/buildroot-bzimage.bin"
|
||||
//},
|
||||
network_relay_url: "<UNUSED>",
|
||||
//bzimage_initrd_from_filesystem: true,
|
||||
cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_free=on",
|
||||
//filesystem: {
|
||||
// baseurl: "com/isoterminal/v86/images/alpine-rootfs-flat",
|
||||
// basefs: "com/isoterminal/v86/images/alpine-fs.json",
|
||||
|
@ -135,56 +94,23 @@ AFRAME.registerComponent('isoterminal', {
|
|||
// instance this component
|
||||
const instance = this.el.cloneNode(false)
|
||||
this.el.sceneEl.appendChild( instance )
|
||||
// instance.addEventListener('DOMready', () => {
|
||||
// console.dir(instance)
|
||||
// debugger
|
||||
// this.runISO(instance.dom)
|
||||
// })
|
||||
|
||||
instance.addEventListener('DOMready', () => {
|
||||
this.runISO(instance.dom)
|
||||
instance.setAttribute("window", `title: ${this.data.iso}; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}`)
|
||||
})
|
||||
|
||||
instance.addEventListener('window.onclose', (e) => {
|
||||
if( !confirm('do you want to kill this virtual machine and all its processes?') ) e.halt = true
|
||||
})
|
||||
|
||||
instance.setAttribute("dom", "")
|
||||
instance.setAttribute("xd", "") // allows flipping between DOM/WebGL when toggling XD-button
|
||||
instance.setAttribute("visible", AFRAME.utils.XD() == '3D' ? 'true' : 'false' )
|
||||
instance.setAttribute("position", AFRAME.utils.XD.getPositionInFrontOfCamera(0.5) )
|
||||
// instance.setAttribute("grabbable","")
|
||||
instance.setAttribute("grabbable","")
|
||||
|
||||
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
|
||||
|
||||
const setupWindow = () => {
|
||||
this.runISO(instance.dom)
|
||||
const com = instance.components['isoterminal']
|
||||
instance.dom.style.display = 'none'
|
||||
let winbox = new WinBox( this.data.iso, {
|
||||
height:'50px',
|
||||
x:"center",
|
||||
y:"center",
|
||||
id: instance.uid, // important hint for html-mesh
|
||||
root: document.querySelector("#overlay"),
|
||||
mount: instance.dom,
|
||||
onclose: () => {
|
||||
if( !confirm('do you want to kill this virtual machine and all its processes?') ) return true
|
||||
instance.dom.style.display = 'none';
|
||||
return false
|
||||
},
|
||||
oncreate: () => {
|
||||
setTimeout( () => {
|
||||
winbox.resize( winbox.width+'px', (instance.dom.offsetHeight+(2*15))+'px' )
|
||||
setTimeout( () => instance.setAttribute("html",`html:#${instance.uid}; cursor:#cursor`), 1000)
|
||||
},100)
|
||||
}
|
||||
});
|
||||
instance.dom.style.display = '' // show
|
||||
|
||||
// hint grabbable's obb-collider to track the window-object
|
||||
instance.components['obb-collider'].data.trackedObject3D = 'components.html.el.object3D.children.0'
|
||||
instance.components['obb-collider'].update()
|
||||
|
||||
// data2event demo
|
||||
//instance.setAttribute("data2event","")
|
||||
//com.data.myvalue = 1
|
||||
//com.data.foo = `instance ${instance.uid}: `
|
||||
//setInterval( () => com.data.myvalue++, 500 )
|
||||
}
|
||||
|
||||
setTimeout( () => setupWindow(), 10 ) // give new components time to init
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
|
@ -242,29 +168,3 @@ in above's case "\nHelloworld application\n" will qualify as header.
|
|||
}
|
||||
|
||||
});
|
||||
|
||||
AFRAME.registerComponent('xterm-shell', {
|
||||
dependencies: ['xterm'],
|
||||
init: function() {
|
||||
const message = 'Run \x1B[1;3;31m\'node server.js\'\x1B[0m to open a shell\r\n'
|
||||
const xterm = this.el.components['xterm']
|
||||
|
||||
xterm.write(message)
|
||||
|
||||
const socket = new WebSocket('ws://localhost:8080/')
|
||||
|
||||
// Listen on data, write it to the terminal
|
||||
socket.onmessage = ({data}) => {
|
||||
xterm.write(data)
|
||||
}
|
||||
|
||||
socket.onclose = () => {
|
||||
xterm.write('\r\nConnection closed.\r\n')
|
||||
}
|
||||
|
||||
// Listen on user input, send it to the connection
|
||||
this.el.addEventListener('xterm-data', ({detail}) => {
|
||||
socket.send(detail)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
@ -80,8 +80,8 @@ AFRAME.registerComponent('launcher', {
|
|||
dom: {
|
||||
scale: 3,
|
||||
events: ['click'],
|
||||
html: (me) => `<div id="iconmenu">loading components..</div>`,
|
||||
css: (me) => `#iconmenu {
|
||||
html: (me) => `<div class="iconmenu">loading components..</div>`,
|
||||
css: (me) => `.iconmenu {
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -98,7 +98,7 @@ AFRAME.registerComponent('launcher', {
|
|||
pointer-events: none;
|
||||
visibility: visible !important;
|
||||
}
|
||||
#iconmenu > button {
|
||||
.iconmenu > button {
|
||||
line-height:0px;
|
||||
pointer-events:all;
|
||||
width: 58px;
|
||||
|
@ -112,27 +112,27 @@ AFRAME.registerComponent('launcher', {
|
|||
font-size:18px;
|
||||
}
|
||||
|
||||
#iconmenu > button:first-child {
|
||||
.iconmenu > button:first-child {
|
||||
border-radius: 5px 0px 0px 5px;
|
||||
border-bottom: 2px solid #BBB;
|
||||
border-left: 2px solid #BBB;
|
||||
padding-bottom:16px;
|
||||
}
|
||||
|
||||
#iconmenu > button:last-child {
|
||||
.iconmenu > button:last-child {
|
||||
border-radius:0px 5px 5px 0px;
|
||||
border-top: 2px solid #BBB;
|
||||
border-right: 2px solid #BBB;
|
||||
padding-top:13px;
|
||||
}
|
||||
|
||||
#iconmenu > button > img {
|
||||
.iconmenu > button > img {
|
||||
transform: translate(0px,-14px);
|
||||
opacity:0.5;
|
||||
padding: 5px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
#iconmenu > button > img:hover{
|
||||
.iconmenu > button > img:hover{
|
||||
background: #AAA;
|
||||
transition:0.gg3s;
|
||||
border-radius: 50%;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
AFRAME.registerComponent('window', {
|
||||
schema:{
|
||||
title: {type:'string',"default":"title"},
|
||||
width: {type:'string'}, // wrap
|
||||
height: {type:'string',"default":'50px'},
|
||||
uid: {type:'string'},
|
||||
attach: {type:'selector'},
|
||||
dom: {type:'selector'},
|
||||
x: {type:'string',"default":"center"},
|
||||
y: {type:'string',"default":"center"}
|
||||
},
|
||||
|
||||
dependencies:['dom'],
|
||||
|
||||
init: function(){
|
||||
setTimeout( () => this.setupWindow(), 10 ) // init after other components
|
||||
},
|
||||
|
||||
setupWindow: function(){
|
||||
if( !this.el.dom ) return console.error('window element requires dom-component as dependency')
|
||||
|
||||
this.el.dom.style.display = 'none'
|
||||
let winbox = new WinBox( this.data.title, {
|
||||
height:this.data.height,
|
||||
height: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,
|
||||
oncreate: () => {
|
||||
this.el.emit('window.oncreate',{})
|
||||
// resize after the dom content has been rendered & updated
|
||||
setTimeout( () => {
|
||||
winbox.resize( winbox.width+'px', (this.data.dom.offsetHeight+(2*15))+'px' )
|
||||
setTimeout( () => this.el.setAttribute("html",`html:#${this.data.uid}; cursor:#cursor`), 1000)
|
||||
this.el.setAttribute("grabbable","")
|
||||
},1000)
|
||||
},
|
||||
onclose: () => {
|
||||
let e = {halt:false}
|
||||
this.el.emit('window.onclose',e)
|
||||
if( e.halt ) return true
|
||||
this.data.dom.style.display = 'none';
|
||||
return false
|
||||
},
|
||||
});
|
||||
this.data.dom.style.display = '' // show
|
||||
|
||||
// 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()
|
||||
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue