add hotkeys + help

This commit is contained in:
Zutatensuppe 2021-04-27 09:46:39 +02:00
parent eb66d72d9d
commit 90590d334e
2 changed files with 110 additions and 17 deletions

View file

@ -47,13 +47,19 @@ const ELEMENTS = {
A: document.createElement('a'), A: document.createElement('a'),
} }
let KEY_LISTENER_OFF = false
function addMenuToDom(gameId) { function addMenuToDom(gameId) {
const previewImageUrl = Game.getImageUrl(gameId) const previewImageUrl = Game.getImageUrl(gameId)
function row (...elements) { function row (...elements) {
const row = ELEMENTS.TR.cloneNode(true) const row = ELEMENTS.TR.cloneNode(true)
for (let el of elements) { for (let el of elements) {
const td = ELEMENTS.TD.cloneNode(true) const td = ELEMENTS.TD.cloneNode(true)
if (typeof el === 'string') {
td.appendChild(document.createTextNode(el))
} else {
td.appendChild(el) td.appendChild(el)
}
row.appendChild(td) row.appendChild(td)
} }
return row return row
@ -103,6 +109,52 @@ function addMenuToDom(gameId) {
nameChangeEl nameChangeEl
) )
const kbd = function(txt) {
const el = document.createElement('kbd')
el.appendChild(document.createTextNode(txt))
return el
}
const h = function(...els) {
const el = ELEMENTS.DIV.cloneNode(true)
for (const other of els) {
if (typeof other === 'string') {
el.appendChild(document.createTextNode(other))
} else {
el.appendChild(other)
}
}
return el
}
const helpEl = ELEMENTS.TABLE.cloneNode(true)
helpEl.classList.add('help')
helpEl.appendChild(row('⬆️ Move up:', h(kbd('W'), '/', kbd('↑'), '/🖱️')))
helpEl.appendChild(row('⬇️ Move down:', h(kbd('S'), '/', kbd('↓'), '/🖱️')))
helpEl.appendChild(row('⬅️ Move left:', h(kbd('A'), '/', kbd('←'), '/🖱️')))
helpEl.appendChild(row('➡️ Move right:', h(kbd('D'), '/', kbd('→'), '/🖱️')))
helpEl.appendChild(row('', h('Move faster by holding ', kbd('Shift'))))
helpEl.appendChild(row('🔍+ Zoom in:', h(kbd('E'), '/🖱️-Wheel')))
helpEl.appendChild(row('🔍- Zoom out:', h(kbd('Q'), '/🖱️-Wheel')))
helpEl.appendChild(row('🖼️ Toggle preview:', h(kbd('Space'))))
helpEl.addEventListener('click', (e) => {
e.stopPropagation()
})
const toggle = (el, disableHotkeys = true) => {
el.classList.toggle('closed')
if (disableHotkeys) {
KEY_LISTENER_OFF = !el.classList.contains('closed')
}
}
const helpOverlay = ELEMENTS.DIV.cloneNode(true)
helpOverlay.classList.add('overlay', 'transparent', 'closed')
helpOverlay.appendChild(helpEl)
helpOverlay.addEventListener('click', () => {
toggle(helpOverlay)
})
const settingsEl = ELEMENTS.TABLE.cloneNode(true) const settingsEl = ELEMENTS.TABLE.cloneNode(true)
settingsEl.classList.add('settings') settingsEl.classList.add('settings')
settingsEl.appendChild(bgColorPickerRow) settingsEl.appendChild(bgColorPickerRow)
@ -116,7 +168,7 @@ function addMenuToDom(gameId) {
settingsOverlay.classList.add('overlay', 'transparent', 'closed') settingsOverlay.classList.add('overlay', 'transparent', 'closed')
settingsOverlay.appendChild(settingsEl) settingsOverlay.appendChild(settingsEl)
settingsOverlay.addEventListener('click', () => { settingsOverlay.addEventListener('click', () => {
settingsOverlay.classList.toggle('closed') toggle(settingsOverlay)
}) })
const previewEl = ELEMENTS.DIV.cloneNode(true) const previewEl = ELEMENTS.DIV.cloneNode(true)
@ -137,12 +189,15 @@ function addMenuToDom(gameId) {
togglePreview() togglePreview()
}) })
const settingsOpenerEl = ELEMENTS.DIV.cloneNode(true) const opener = (txt, overlay, disableHotkeys = true) => {
settingsOpenerEl.classList.add('opener') const el = ELEMENTS.DIV.cloneNode(true)
settingsOpenerEl.appendChild(document.createTextNode('🛠️ Settings')) el.classList.add('opener')
settingsOpenerEl.addEventListener('click', () => { el.appendChild(document.createTextNode(txt))
settingsOverlay.classList.toggle('closed') el.addEventListener('click', () => {
toggle(overlay, disableHotkeys)
}) })
return el
}
const homeEl = ELEMENTS.A.cloneNode(true) const homeEl = ELEMENTS.A.cloneNode(true)
homeEl.classList.add('opener') homeEl.classList.add('opener')
@ -150,18 +205,16 @@ function addMenuToDom(gameId) {
homeEl.target = '_blank' homeEl.target = '_blank'
homeEl.href = '/' homeEl.href = '/'
const previewOpenerEl = ELEMENTS.DIV.cloneNode(true) const settingsOpenerEl = opener('🛠️ Settings', settingsOverlay)
previewOpenerEl.classList.add('opener') const previewOpenerEl = opener('🖼️ Preview', previewOverlay, false)
previewOpenerEl.appendChild(document.createTextNode('🖼️ Preview')) const helpOpenerEl = opener(' Help', helpOverlay)
previewOpenerEl.addEventListener('click', () => {
previewOverlay.classList.toggle('closed')
})
const tabsEl = ELEMENTS.DIV.cloneNode(true) const tabsEl = ELEMENTS.DIV.cloneNode(true)
tabsEl.classList.add('tabs') tabsEl.classList.add('tabs')
tabsEl.appendChild(homeEl) tabsEl.appendChild(homeEl)
tabsEl.appendChild(previewOpenerEl) tabsEl.appendChild(previewOpenerEl)
tabsEl.appendChild(settingsOpenerEl) tabsEl.appendChild(settingsOpenerEl)
tabsEl.appendChild(helpOpenerEl)
const menuEl = ELEMENTS.DIV.cloneNode(true) const menuEl = ELEMENTS.DIV.cloneNode(true)
menuEl.classList.add('menu') menuEl.classList.add('menu')
@ -250,6 +303,7 @@ function addMenuToDom(gameId) {
document.body.appendChild(settingsOverlay) document.body.appendChild(settingsOverlay)
document.body.appendChild(previewOverlay) document.body.appendChild(previewOverlay)
document.body.appendChild(helpOverlay)
document.body.appendChild(timerEl) document.body.appendChild(timerEl)
document.body.appendChild(menuEl) document.body.appendChild(menuEl)
document.body.appendChild(scoresEl) document.body.appendChild(scoresEl)
@ -296,6 +350,9 @@ export default class EventAdapter {
canvas.addEventListener('wheel', this._wheel.bind(this)) canvas.addEventListener('wheel', this._wheel.bind(this))
window.addEventListener('keydown', (ev) => { window.addEventListener('keydown', (ev) => {
if (KEY_LISTENER_OFF) {
return
}
if (ev.key === 'Shift') { if (ev.key === 'Shift') {
this.SHIFT = true this.SHIFT = true
} else if (ev.key === 'ArrowUp' || ev.key === 'w' || ev.key === 'W') { } else if (ev.key === 'ArrowUp' || ev.key === 'w' || ev.key === 'W') {
@ -313,6 +370,9 @@ export default class EventAdapter {
} }
}) })
window.addEventListener('keyup', (ev) => { window.addEventListener('keyup', (ev) => {
if (KEY_LISTENER_OFF) {
return
}
if (ev.key === 'Shift') { if (ev.key === 'Shift') {
this.SHIFT = false this.SHIFT = false
} else if (ev.key === 'ArrowUp' || ev.key === 'w' || ev.key === 'W') { } else if (ev.key === 'ArrowUp' || ev.key === 'w' || ev.key === 'W') {
@ -534,6 +594,9 @@ async function main() {
} }
window.addEventListener('keypress', (ev) => { window.addEventListener('keypress', (ev) => {
if (KEY_LISTENER_OFF) {
return
}
if (ev.key === ' ') { if (ev.key === ' ') {
togglePreview() togglePreview()
} }
@ -846,7 +909,6 @@ async function main() {
// Names // Names
ctx.fillStyle = 'white' ctx.fillStyle = 'white'
ctx.font = '10px sans-serif'
ctx.textAlign = 'center' ctx.textAlign = 'center'
for (let [txt, x, y] of texts) { for (let [txt, x, y] of texts) {
ctx.fillText(txt, x, y) ctx.fillText(txt, x, y)

View file

@ -13,7 +13,13 @@ body {
background: #2b2b2b; background: #2b2b2b;
color: var(--main-color); color: var(--main-color);
height: 100%; height: 100%;
font-family: sans-serif; }
* {
font-family: monospace;
font-size: 15px;
}
h1, h2, h3, h4 {
font-size: 20px;
} }
a { color: var(--link-color); text-decoration: none; } a { color: var(--link-color); text-decoration: none; }
@ -72,6 +78,18 @@ a:hover { color: var(--link-hover-color); }
background: transparent; background: transparent;
} }
.help {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
background: var(--bg-color);
padding: 5px;
border: solid 1px black;
box-shadow: 0 0 10px 0 rgba(0,0,0,.7);
z-index: 1;
}
.settings { .settings {
position: absolute; position: absolute;
left: 50%; left: 50%;
@ -135,7 +153,6 @@ input:focus {
} }
.btn { .btn {
font: 15px sans-serif;
display: inline-block; display: inline-block;
background: var(--input-bg-color); background: var(--input-bg-color);
color: var(--link-color); color: var(--link-color);
@ -214,3 +231,17 @@ input:focus {
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: #222; background-color: #222;
} }
kbd {
background-color: #eee;
border-radius: 3px;
border: 1px solid #b4b4b4;
box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 0 0 rgba(255, 255, 255, .7) inset;
color: #333;
display: inline-block;
font-size: .85em;
font-weight: 700;
line-height: 1;
padding: 2px 4px;
white-space: nowrap;
}