better & tab-able buttons/notifications #accessibility
This commit is contained in:
parent
093de1ec6f
commit
0bc5fa86d1
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Sat Jun 15 05:46:02 PM CEST 2024
|
||||
* v0.5.1 generated at Mon Jun 17 12:41:29 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Sat Jun 15 05:46:02 PM CEST 2024
|
||||
* v0.5.1 generated at Mon Jun 17 12:41:29 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -284,6 +284,8 @@ window.accessibility = (opts) => new Proxy({
|
|||
.replace(/&/,' and ')
|
||||
.replace(/=/,' is ')
|
||||
}
|
||||
if( str == this.speak.lastStr ) return // no duplicates
|
||||
this.speak.lastStr = str
|
||||
let speech = window.speechSynthesis
|
||||
let utterance = new SpeechSynthesisUtterance( str )
|
||||
this.speak_voices = speech.getVoices().length
|
||||
|
@ -304,6 +306,18 @@ window.accessibility = (opts) => new Proxy({
|
|||
|
||||
init(){
|
||||
|
||||
this
|
||||
.speakArrowKeys()
|
||||
.setupListeners()
|
||||
.setupPersistance()
|
||||
.setupHrefCycling()
|
||||
.setupSpeechKillOnEscape()
|
||||
|
||||
setTimeout( () => this.initCommands(), 200 )
|
||||
},
|
||||
|
||||
speakArrowKeys(){
|
||||
// speak arrow keys
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if( !this.speak_keyboard ) return
|
||||
let k = e.key
|
||||
|
@ -315,6 +329,60 @@ window.accessibility = (opts) => new Proxy({
|
|||
}
|
||||
this.speak(k,{override:true})
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
setupSpeechKillOnEscape(){
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if( e.key == "Escape" ){
|
||||
this.speak("stop",{override:true})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
setupHrefCycling(){
|
||||
// speak arrow keys
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if( e.key != 'Tab') return
|
||||
let subScene = xrf.scene.getObjectByName( xrf.frag.pos.last )
|
||||
if( !subScene ) subScene = xrf.scene
|
||||
let cache = this.setupHrefCycling.cache = this.setupHrefCycling.cache || {current: 0}
|
||||
let objects = []
|
||||
subScene.traverse( (n) => (n.userData.href || n.userData['aria-description']) && objects.push(n) )
|
||||
|
||||
const highlight = (n) => {
|
||||
if( this.helper){
|
||||
if( this.helper.selected == n.uuid ) return // already selected
|
||||
xrf.scene.remove(this.helper)
|
||||
}
|
||||
this.selected = n
|
||||
this.helper = new THREE.BoxHelper( n, 0xFF00FF )
|
||||
this.helper.computeLineDistances()
|
||||
this.helper.material.linewidth = 8
|
||||
this.helper.material.color = xrf.focusLine.material.color
|
||||
this.helper.material.dashSize = xrf.focusLine.material.dashSize
|
||||
this.helper.material.gapSize = xrf.focusLine.material.gapSize
|
||||
this.helper.selected = n.uuid
|
||||
xrf.scene.add(this.helper)
|
||||
|
||||
notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>link:</b> ${n.userData['href']}` :'') )
|
||||
}
|
||||
|
||||
// ensure valid href
|
||||
cache.current = cache.current % objects.length
|
||||
highlight( objects[cache.current] )
|
||||
console.log(objects[cache.current].userData.href)
|
||||
|
||||
// increment to next
|
||||
cache.current = cache.current + 1
|
||||
|
||||
e.preventDefault()
|
||||
return false
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
setupListeners(){
|
||||
|
||||
document.addEventListener('$menu:buttons:render', (e) => {
|
||||
let $ = e.detail
|
||||
|
@ -354,8 +422,10 @@ window.accessibility = (opts) => new Proxy({
|
|||
network.posName = opts.frag.pos.string
|
||||
}
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
setTimeout( () => this.initCommands(), 200 )
|
||||
setupPersistance(){
|
||||
// auto-enable if previously enabled
|
||||
if( window.localStorage.getItem("accessibility") === 'true' || xrf.navigator.URI.XRF.accessible ){
|
||||
setTimeout( () => {
|
||||
|
@ -363,11 +433,14 @@ window.accessibility = (opts) => new Proxy({
|
|||
this.setFontSize()
|
||||
}, 100 )
|
||||
}
|
||||
return this
|
||||
},
|
||||
|
||||
initCommands(){
|
||||
|
||||
document.addEventListener('chat.command.help', (e) => {
|
||||
e.detail.message += `<br><b class="badge"><Escape></b> silence TTS `
|
||||
e.detail.message += `<br><b class="badge"><Tab></b> cycle [href] buttons / silence TTS `
|
||||
e.detail.message += `<br><b class="badge">/fontsize <number></b> set fontsize (default=14) `
|
||||
})
|
||||
|
||||
|
@ -572,6 +645,7 @@ window.frontend = (opts) => new Proxy({
|
|||
</div>
|
||||
`,
|
||||
el: null,
|
||||
notify_links: true,
|
||||
plugin: {},
|
||||
xrf,
|
||||
|
||||
|
@ -651,7 +725,7 @@ window.frontend = (opts) => new Proxy({
|
|||
setTimeout( () => {
|
||||
let instructions = AFRAME.utils.device.isMobile()
|
||||
? "hold 2-3 fingers to move forward/backward"
|
||||
: "use WASD-keys and mouse-drag to move around"
|
||||
: "use W A S D keys and mouse-drag to move around"
|
||||
window.notify(instructions,{timeout:false})
|
||||
xrf.addEventListener('pos', (opts) => {
|
||||
let pos = opts.frag.pos.string
|
||||
|
@ -662,7 +736,7 @@ window.frontend = (opts) => new Proxy({
|
|||
xrf.addEventListener('href', (data) => {
|
||||
if( !data.selected ) return
|
||||
|
||||
let html = `<b class="badge">${data.mesh.isSRC && !data.mesh.portal ? 'src' : 'href'}</b>${ data.xrf ? data.xrf.string : data.mesh.userData.src}<br>`
|
||||
let html = this.notify_links ? `<b class="badge">${data.mesh.isSRC && !data.mesh.portal ? 'src' : 'href'}</b>${ data.xrf ? data.xrf.string : data.mesh.userData.src}<br>` : ''
|
||||
let metadata = data.mesh.userData
|
||||
let meta = xrf.Parser.getMetaData()
|
||||
|
||||
|
@ -682,6 +756,7 @@ window.frontend = (opts) => new Proxy({
|
|||
let transcript = xrf.sceneToTranscript(root,data.mesh)
|
||||
if( transcript.length ) html += `<br><b>transcript:</b><br><div class="transcript">${transcript}</div>`
|
||||
if (hasMeta && !data.mesh.portal && metadata.XRF.src ) html += `<br><br><a class="btn" style="float:right" onclick="xrf.navigator.to('${data.mesh.userData.href}')">Visit embedded scene</a>`
|
||||
if( !html ) return
|
||||
window.notify(html,{timeout: 7000 * (hasMeta ? 1.5 : 1) })
|
||||
})
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Sat Jun 15 05:46:02 PM CEST 2024
|
||||
* v0.5.1 generated at Mon Jun 17 12:41:29 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Sat Jun 15 05:46:02 PM CEST 2024
|
||||
* v0.5.1 generated at Mon Jun 17 12:41:29 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
<script>
|
||||
|
||||
document.addEventListener('$menu:ready', (e) => {
|
||||
let {$menu} = e.detail
|
||||
frontend.notify_links = true // shows href/src's as notifications when hovering buttons
|
||||
// add your menubuttons:
|
||||
let {$menu} = e.detail
|
||||
$menu.buttons = $menu.buttons.concat([
|
||||
`<a class="btn" aria-label="button" aria-title="menu button" onclick="$menu.showAbout()"><i class="gg-info"></i> about</a><br>`
|
||||
])
|
||||
|
|
|
@ -32,6 +32,8 @@ window.accessibility = (opts) => new Proxy({
|
|||
.replace(/&/,' and ')
|
||||
.replace(/=/,' is ')
|
||||
}
|
||||
if( str == this.speak.lastStr ) return // no duplicates
|
||||
this.speak.lastStr = str
|
||||
let speech = window.speechSynthesis
|
||||
let utterance = new SpeechSynthesisUtterance( str )
|
||||
this.speak_voices = speech.getVoices().length
|
||||
|
@ -52,6 +54,18 @@ window.accessibility = (opts) => new Proxy({
|
|||
|
||||
init(){
|
||||
|
||||
this
|
||||
.speakArrowKeys()
|
||||
.setupListeners()
|
||||
.setupPersistance()
|
||||
.setupHrefCycling()
|
||||
.setupSpeechKillOnEscape()
|
||||
|
||||
setTimeout( () => this.initCommands(), 200 )
|
||||
},
|
||||
|
||||
speakArrowKeys(){
|
||||
// speak arrow keys
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if( !this.speak_keyboard ) return
|
||||
let k = e.key
|
||||
|
@ -63,6 +77,60 @@ window.accessibility = (opts) => new Proxy({
|
|||
}
|
||||
this.speak(k,{override:true})
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
setupSpeechKillOnEscape(){
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if( e.key == "Escape" ){
|
||||
this.speak("stop",{override:true})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
setupHrefCycling(){
|
||||
// speak arrow keys
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if( e.key != 'Tab') return
|
||||
let subScene = xrf.scene.getObjectByName( xrf.frag.pos.last )
|
||||
if( !subScene ) subScene = xrf.scene
|
||||
let cache = this.setupHrefCycling.cache = this.setupHrefCycling.cache || {current: 0}
|
||||
let objects = []
|
||||
subScene.traverse( (n) => (n.userData.href || n.userData['aria-description']) && objects.push(n) )
|
||||
|
||||
const highlight = (n) => {
|
||||
if( this.helper){
|
||||
if( this.helper.selected == n.uuid ) return // already selected
|
||||
xrf.scene.remove(this.helper)
|
||||
}
|
||||
this.selected = n
|
||||
this.helper = new THREE.BoxHelper( n, 0xFF00FF )
|
||||
this.helper.computeLineDistances()
|
||||
this.helper.material.linewidth = 8
|
||||
this.helper.material.color = xrf.focusLine.material.color
|
||||
this.helper.material.dashSize = xrf.focusLine.material.dashSize
|
||||
this.helper.material.gapSize = xrf.focusLine.material.gapSize
|
||||
this.helper.selected = n.uuid
|
||||
xrf.scene.add(this.helper)
|
||||
|
||||
notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>link:</b> ${n.userData['href']}` :'') )
|
||||
}
|
||||
|
||||
// ensure valid href
|
||||
cache.current = cache.current % objects.length
|
||||
highlight( objects[cache.current] )
|
||||
console.log(objects[cache.current].userData.href)
|
||||
|
||||
// increment to next
|
||||
cache.current = cache.current + 1
|
||||
|
||||
e.preventDefault()
|
||||
return false
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
setupListeners(){
|
||||
|
||||
document.addEventListener('$menu:buttons:render', (e) => {
|
||||
let $ = e.detail
|
||||
|
@ -102,8 +170,10 @@ window.accessibility = (opts) => new Proxy({
|
|||
network.posName = opts.frag.pos.string
|
||||
}
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
setTimeout( () => this.initCommands(), 200 )
|
||||
setupPersistance(){
|
||||
// auto-enable if previously enabled
|
||||
if( window.localStorage.getItem("accessibility") === 'true' || xrf.navigator.URI.XRF.accessible ){
|
||||
setTimeout( () => {
|
||||
|
@ -111,11 +181,14 @@ window.accessibility = (opts) => new Proxy({
|
|||
this.setFontSize()
|
||||
}, 100 )
|
||||
}
|
||||
return this
|
||||
},
|
||||
|
||||
initCommands(){
|
||||
|
||||
document.addEventListener('chat.command.help', (e) => {
|
||||
e.detail.message += `<br><b class="badge"><Escape></b> silence TTS `
|
||||
e.detail.message += `<br><b class="badge"><Tab></b> cycle [href] buttons / silence TTS `
|
||||
e.detail.message += `<br><b class="badge">/fontsize <number></b> set fontsize (default=14) `
|
||||
})
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ window.frontend = (opts) => new Proxy({
|
|||
</div>
|
||||
`,
|
||||
el: null,
|
||||
notify_links: true,
|
||||
plugin: {},
|
||||
xrf,
|
||||
|
||||
|
@ -92,7 +93,7 @@ window.frontend = (opts) => new Proxy({
|
|||
setTimeout( () => {
|
||||
let instructions = AFRAME.utils.device.isMobile()
|
||||
? "hold 2-3 fingers to move forward/backward"
|
||||
: "use WASD-keys and mouse-drag to move around"
|
||||
: "use W A S D keys and mouse-drag to move around"
|
||||
window.notify(instructions,{timeout:false})
|
||||
xrf.addEventListener('pos', (opts) => {
|
||||
let pos = opts.frag.pos.string
|
||||
|
@ -103,7 +104,7 @@ window.frontend = (opts) => new Proxy({
|
|||
xrf.addEventListener('href', (data) => {
|
||||
if( !data.selected ) return
|
||||
|
||||
let html = `<b class="badge">${data.mesh.isSRC && !data.mesh.portal ? 'src' : 'href'}</b>${ data.xrf ? data.xrf.string : data.mesh.userData.src}<br>`
|
||||
let html = this.notify_links ? `<b class="badge">${data.mesh.isSRC && !data.mesh.portal ? 'src' : 'href'}</b>${ data.xrf ? data.xrf.string : data.mesh.userData.src}<br>` : ''
|
||||
let metadata = data.mesh.userData
|
||||
let meta = xrf.Parser.getMetaData()
|
||||
|
||||
|
@ -123,6 +124,7 @@ window.frontend = (opts) => new Proxy({
|
|||
let transcript = xrf.sceneToTranscript(root,data.mesh)
|
||||
if( transcript.length ) html += `<br><b>transcript:</b><br><div class="transcript">${transcript}</div>`
|
||||
if (hasMeta && !data.mesh.portal && metadata.XRF.src ) html += `<br><br><a class="btn" style="float:right" onclick="xrf.navigator.to('${data.mesh.userData.href}')">Visit embedded scene</a>`
|
||||
if( !html ) return
|
||||
window.notify(html,{timeout: 7000 * (hasMeta ? 1.5 : 1) })
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue