fix requestAnimationFrame mystery
/ mirror_to_github (push) Successful in 20s Details
/ test (push) Successful in 5s Details

This commit is contained in:
Leon van Kammen 2024-07-04 23:00:44 +02:00
parent 9498d9297e
commit c668a8ba8f
4 changed files with 53 additions and 24 deletions

View File

@ -53,6 +53,7 @@ AFRAME.registerComponent('dom',{
.assignUniqueID()
.scaleDOMvsXR()
.triggerKeyboardForInputs()
.stubRequestAnimationFrame()
document.querySelector('#overlay').appendChild(this.el.dom)
this.el.emit('DOMready',{el: this.el.dom})
@ -121,6 +122,14 @@ AFRAME.registerComponent('dom',{
input.addEventListener('click', triggerKeyboard )
})
return this
},
stubRequestAnimationFrame: function(){
// stub, because WebXR with overrule this (it will not call the callback as expected in immersive mode)
const requestAnimationFrame = window.requestAnimationFrame
window.requestAnimationFrame = (cb) => {
setTimeout( cb, 25 )
}
}
})

View File

@ -1,9 +1,10 @@
AFRAME.registerComponent('isoterminal', {
schema: {
iso: { type:"string", "default":"com/isoterminal/xrsh.iso" },
cols: { type: 'number', default: 120 },
rows: { type: 'number', default: 30 },
transparent: { type:'boolean', default:false } // need good gpu
cols: { type: 'number',"default": 120 },
rows: { type: 'number',"default": 30 },
padding:{ type: 'number',"default": 15 },
transparent: { type:'boolean', "default":false } // need good gpu
},
init: function(){
@ -12,7 +13,6 @@ 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", //
xtermcss: "https://unpkg.com/xterm@3.12.0/dist/xterm.css",
@ -31,23 +31,25 @@ AFRAME.registerComponent('isoterminal', {
css: (me) => `.isoterminal{
background:#000;
padding:15px;
padding: ${me.com.data.padding}px;
/*overflow:hidden; */
}
.isoterminal *{
white-space: pre;
font-size: 14px;
font-family: Liberation Mono,DejaVu Sans Mono,Courier New,monospace;
display: block;
font-weight:700;
display:inline;
overflow: hidden;
}
.terminal{
padding:15px;
}`
.wb-body:has(> .isoterminal){ background: #000; }
.isoterminal div{ display:block; }
.isoterminal span{ display: inline }
`
},
runISO: function(dom){
var emulator = window.emulator = new V86({
var emulator = window.emulator = dom.emulator = new V86({
wasm_path: "com/isoterminal/v86.wasm",
memory_size: 32 * 1024 * 1024,
vga_memory_size: 2 * 1024 * 1024,
@ -75,13 +77,17 @@ AFRAME.registerComponent('isoterminal', {
screen_dummy: true,
autostart: true,
});
//setTimeout( () => {
// window.requestAnimationFrame = requestAnimationFrame
//},1000)
},
events:{
// combined AFRAME+DOM reactive events
click: function(e){ }, //
keydown: function(e){ }, //
keydown: function(e){ },
// reactive events for this.data updates
myvalue: function(e){ this.el.dom.querySelector('b').innerText = this.data.myvalue },
@ -101,6 +107,17 @@ AFRAME.registerComponent('isoterminal', {
instance.setAttribute("window", `title: ${this.data.iso}; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}`)
})
instance.addEventListener('window.oncreate', (e) => {
// resize after the dom content has been rendered & updated
setTimeout( () => {
let spans = [...instance.dom.querySelectorAll('span')]
instance.winbox.resize(
(spans[0].offsetWidth + (2*this.data.padding))+'px',
((spans.length * spans[0].offsetHeight) ) +'px'
)
},1200)
})
instance.addEventListener('window.onclose', (e) => {
if( !confirm('do you want to kill this virtual machine and all its processes?') ) e.halt = true
})
@ -111,13 +128,12 @@ AFRAME.registerComponent('isoterminal', {
instance.setAttribute("position", AFRAME.utils.XD.getPositionInFrontOfCamera(0.5) )
instance.setAttribute("grabbable","")
this.el.sceneEl.addEventListener('enter-vr', function(){
instance.dom.focus()
console.log("focusing terminal")
})
const focus = () => document.querySelector('canvas.a-canvas').focus()
instance.addEventListener('obbcollisionstarted', focus )
this.el.sceneEl.addEventListener('enter-vr', focus )
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
},
}
},

View File

@ -10,19 +10,23 @@ AFRAME.registerComponent('window', {
y: {type:'string',"default":"center"}
},
dependencies:['dom'],
dependencies:{
dom: "com/dom.js",
html: "https://unpkg.com/aframe-htmlmesh@2.1.0/build/aframe-html.js", // html to AFRAME
},
init: function(){
setTimeout( () => this.setupWindow(), 10 ) // init after other components
},
setupWindow: function(){
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 = new WinBox( this.data.title, {
let winbox = this.el.winbox = new WinBox( this.data.title, {
height:this.data.height,
height:this.data.width,
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
@ -32,7 +36,7 @@ AFRAME.registerComponent('window', {
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' )
winbox.resize( this.el.dom.offsetWidth+'px', this.el.dom.offsetHeight+'px' )
setTimeout( () => this.el.setAttribute("html",`html:#${this.data.uid}; cursor:#cursor`), 1000)
this.el.setAttribute("grabbable","")
},1000)

View File

@ -36,7 +36,7 @@ AFRAME.registerComponent('xd', {
// draw a button so we can toggle apps between 2D / XR
toggle: function(state){
state = state || !document.body.className.match(/XR/)
state = state != undefined ? state : state || !document.body.className.match(/XR/)
document.body.classList[ state ? 'add' : 'remove'](['XR'])
AFRAME.scenes[0].emit( state ? '3D' : '2D')
},