lx-music-desktop/src/renderer/utils/keyBind.js

110 lines
2.4 KiB
JavaScript

import { isMac } from '../../common/utils'
const downKeys = new Set()
const handleEvent = (type, event, keys) => {
if (isMac) {
let index = keys.indexOf('meta')
if (index > -1) keys.splice(index, 1, 'mod')
} else {
let index = keys.indexOf('ctrl')
if (index > -1) keys.splice(index, 1, 'mod')
}
let key = keys.join('+')
switch (type) {
case 'down':
downKeys.add(key)
break
case 'up':
downKeys.delete(key)
break
}
handleSendEvent(key, type, event, keys)
}
// 修饰键处理
const eventModifiers = event => {
let modifiers = []
if (event.ctrlKey) modifiers.push('ctrl')
if (event.shiftKey) modifiers.push('shift')
if (event.altKey) modifiers.push('alt')
if (event.metaKey) modifiers.push('meta')
return modifiers
}
// 是否忽略事件(表单元素等默认忽略)
const assertStopCallback = element => {
// if the element has the class "keybind" then no need to stop
if (element.classList.contains('key-bind')) return false
// stop for input, select, and textarea
switch (element.tagName) {
case 'INPUT':
case 'SELECT':
case 'TEXTAREA':
return true
default:
return element.isContentEditable
}
}
const handleKeyDown = event => {
if (assertStopCallback(event.target)) return
// event.preventDefault()
let keys = eventModifiers(event)
switch (event.key) {
case 'Control':
case 'Alt':
case 'Meta':
case 'Shift':
break
default:
keys.push(event.key.toLowerCase())
break
}
handleEvent('down', event, keys)
}
const handleKeyUp = event => {
if (assertStopCallback(event.target)) return
event.preventDefault()
let keys = eventModifiers(event)
switch (event.key) {
case 'Control':
keys.push('ctrl')
break
default:
keys.push(event.key.toLowerCase())
break
}
handleEvent('up', event, keys)
}
let handleSendEvent
const bindKey = (handle = () => {}) => {
handleSendEvent = handle
document.addEventListener('keydown', handleKeyDown)
document.addEventListener('keyup', handleKeyUp)
}
const unbindKey = () => {
document.removeEventListener('keydown', handleKeyDown)
document.removeEventListener('keyup', handleKeyUp)
}
const clearDownKeys = () => {
for (const key of downKeys) {
handleSendEvent(key, 'up')
}
downKeys.clear()
}
export default {
bindKey,
unbindKey,
clearDownKeys,
}