Last active
February 18, 2023 15:20
-
-
Save ecwu/fc2a5a143d2d3a29fb9c459deaf009b8 to your computer and use it in GitHub Desktop.
Custom input-overlay preset that shows keyboard and mouse (only left and right click) history
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<!-- A usable HTML template for input-history overlay using Browser Source and Websocket --> | |
<!-- ONLY KEYBOARD INPUT AS OF NOW --> | |
<!-- By: https://github.com/christiankyle-ching/ --> | |
<!-- Edited By: https://github.com/ecwu/ --> | |
<head> | |
<meta charset="utf-8" /> | |
<title>input-history Windows</title> | |
<style> | |
/* Zero out default values */ | |
* { | |
margin: 0; | |
padding: 0; | |
} | |
body { | |
font-family: Arial, Helvetica, sans-serif; | |
font-size: 48px; | |
color: white; | |
overflow: hidden; | |
} | |
/* #region History List */ | |
div#history { | |
/* Apply padding top to place first keys on the bottom part */ | |
padding-top: 100vh; | |
list-style-type: none; | |
} | |
/* Animation for hide timeout */ | |
p.key-combination.hidden { | |
opacity: 0; | |
transition-property: opacity; | |
transition-timing-function: ease-out; | |
transition-duration: 1s; | |
} | |
p.key-combination > * { | |
/* For line-height */ | |
margin-top: 0.5em; | |
vertical-align: middle; | |
} | |
p.key-combination > .separator { | |
display: inline-block; | |
/* Spacing on sides of separator */ | |
margin-left: 0.25em; | |
margin-right: 0.25em; | |
} | |
span.key { | |
display: inline-flex; | |
border-radius: 0.25em; | |
padding: 0.25em; | |
background-color: rgba(0, 0, 0, 0.75); | |
white-space: nowrap; | |
} | |
/* #endregion */ | |
/* #region Icons */ | |
#icons-container { | |
visibility: collapse; | |
} | |
.icon-sm { | |
width: 1em; | |
height: 1em; | |
display: block; | |
margin: auto; | |
} | |
/* #endregion */ | |
</style> | |
</head> | |
<body> | |
<!-- #region Icons --> | |
<div id="icons-container"> | |
<!-- Get Icons from FontAwesome --> | |
<!-- Copy SVG Code --> | |
<!-- Windows Key - VC_META_L / VC_META_R --> | |
<svg | |
id="SVG_VC_META" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 448 512" | |
> | |
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> | |
<path | |
d="M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z" | |
/> | |
</svg> | |
<!-- Arrow Left --> | |
<svg | |
id="SVG_VC_LEFT" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 512 512" | |
> | |
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> | |
<path | |
d="M512 256C512 273.7 497.7 288 480 288H160.1l0 72c0 9.547-5.66 18.19-14.42 22c-8.754 3.812-18.95 2.077-25.94-4.407l-112.1-104c-10.24-9.5-10.24-25.69 0-35.19l112.1-104c6.992-6.484 17.18-8.218 25.94-4.406C154.4 133.8 160.1 142.5 160.1 151.1L160.1 224H480C497.7 224 512 238.3 512 256z" | |
/> | |
</svg> | |
<!-- Arrow Right --> | |
<svg | |
id="SVG_VC_RIGHT" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 512 512" | |
> | |
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> | |
<path | |
d="M504.3 273.6l-112.1 104c-6.992 6.484-17.18 8.218-25.94 4.406c-8.758-3.812-14.42-12.45-14.42-21.1L351.9 288H32C14.33 288 .0002 273.7 .0002 255.1S14.33 224 32 224h319.9l0-72c0-9.547 5.66-18.19 14.42-22c8.754-3.809 18.95-2.075 25.94 4.41l112.1 104C514.6 247.9 514.6 264.1 504.3 273.6z" | |
/> | |
</svg> | |
<!-- Arrow Up --> | |
<svg | |
id="SVG_VC_UP" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 320 512" | |
> | |
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> | |
<path | |
d="M285.1 145.7c-3.81 8.758-12.45 14.42-21.1 14.42L192 160.1V480c0 17.69-14.33 32-32 32s-32-14.31-32-32V160.1L55.1 160.1c-9.547 0-18.19-5.658-22-14.42c-3.811-8.758-2.076-18.95 4.408-25.94l104-112.1c9.498-10.24 25.69-10.24 35.19 0l104 112.1C288.1 126.7 289.8 136.9 285.1 145.7z" | |
/> | |
</svg> | |
<!-- Arrow Down --> | |
<svg | |
id="SVG_VC_DOWN" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 320 512" | |
> | |
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> | |
<path | |
d="M281.6 392.3l-104 112.1c-9.498 10.24-25.69 10.24-35.19 0l-104-112.1c-6.484-6.992-8.219-17.18-4.404-25.94c3.811-8.758 12.45-14.42 21.1-14.42H128V32c0-17.69 14.33-32 32-32S192 14.31 192 32v319.9h72c9.547 0 18.19 5.66 22 14.42C289.8 375.1 288.1 385.3 281.6 392.3z" | |
/> | |
</svg> | |
</div> | |
<!-- #endregion --> | |
<div id="history"></div> | |
</body> | |
<script> | |
/** | |
* Keycodes from: https://github.com/kwhat/libuiohook/blob/1.2/include/uiohook.h | |
* [0] -> libuiohook key | |
* [1] -> optional alias | |
* | |
* Comment out keys that you don't want to show | |
*/ | |
var KEYCODES = { | |
/* Begin Virtual Key Codes */ | |
0x0001: ["VC_ESCAPE", "ESC"], | |
// Begin Function Keys | |
0x003b: ["VC_F1", "F1"], | |
0x003c: ["VC_F2", "F2"], | |
0x003d: ["VC_F3", "F3"], | |
0x003e: ["VC_F4", "F4"], | |
0x003f: ["VC_F5", "F5"], | |
0x0040: ["VC_F6", "F6"], | |
0x0041: ["VC_F7", "F7"], | |
0x0042: ["VC_F8", "F8"], | |
0x0043: ["VC_F9", "F9"], | |
0x0044: ["VC_F10", "F10"], | |
0x0057: ["VC_F11", "F11"], | |
0x0058: ["VC_F12", "F12"], | |
0x005b: ["VC_F13", ""], | |
0x005c: ["VC_F14", ""], | |
0x005d: ["VC_F15", ""], | |
0x0063: ["VC_F16", ""], | |
0x0064: ["VC_F17", ""], | |
0x0065: ["VC_F18", ""], | |
0x0066: ["VC_F19", ""], | |
0x0067: ["VC_F20", ""], | |
0x0068: ["VC_F21", ""], | |
0x0069: ["VC_F22", ""], | |
0x006a: ["VC_F23", ""], | |
0x006b: ["VC_F24", ""], | |
// End Function Keys | |
// Begin Alphanumeric Zone | |
0x0029: ["VC_BACKQUOTE", "`"], | |
0x0002: ["VC_1", "1"], | |
0x0003: ["VC_2", "2"], | |
0x0004: ["VC_3", "3"], | |
0x0005: ["VC_4", "4"], | |
0x0006: ["VC_5", "5"], | |
0x0007: ["VC_6", "6"], | |
0x0008: ["VC_7", "7"], | |
0x0009: ["VC_8", "8"], | |
0x000a: ["VC_9", "9"], | |
0x000b: ["VC_0", "0"], | |
0x000c: ["VC_MINUS", "-"], // '-' | |
0x000d: ["VC_EQUALS", "="], // '=' | |
0x000e: ["VC_BACKSPACE", "退格"], | |
0x000f: ["VC_TAB", "TAB"], | |
0x003a: ["VC_CAPS_LOCK", "大写锁定"], | |
0x001e: ["VC_A", "A"], | |
0x0030: ["VC_B", "B"], | |
0x002e: ["VC_C", "C"], | |
0x0020: ["VC_D", "D"], | |
0x0012: ["VC_E", "E"], | |
0x0021: ["VC_F", "F"], | |
0x0022: ["VC_G", "G"], | |
0x0023: ["VC_H", "H"], | |
0x0017: ["VC_I", "I"], | |
0x0024: ["VC_J", "J"], | |
0x0025: ["VC_K", "K"], | |
0x0026: ["VC_L", "L"], | |
0x0032: ["VC_M", "M"], | |
0x0031: ["VC_N", "N"], | |
0x0018: ["VC_O", "O"], | |
0x0019: ["VC_P", "P"], | |
0x0010: ["VC_Q", "Q"], | |
0x0013: ["VC_R", "R"], | |
0x001f: ["VC_S", "S"], | |
0x0014: ["VC_T", "T"], | |
0x0016: ["VC_U", "U"], | |
0x002f: ["VC_V", "V"], | |
0x0011: ["VC_W", "W"], | |
0x002d: ["VC_X", "X"], | |
0x0015: ["VC_Y", "Y"], | |
0x002c: ["VC_Z", "Z"], | |
0x001a: ["VC_OPEN_BRACKET", "["], // '[' | |
0x001b: ["VC_CLOSE_BRACKET", "]"], // ']' | |
0x002b: ["VC_BACK_SLASH", "\\"], // '\' | |
0x0027: ["VC_SEMICOLON", ";"], // ';' | |
0x0028: ["VC_QUOTE", "'"], | |
0x001c: ["VC_ENTER", "回车"], | |
0x0033: ["VC_COMMA", ","], // ', ""],' | |
0x0034: ["VC_PERIOD", "."], // '.' | |
0x0035: ["VC_SLASH", "/"], // '/' | |
0x0039: ["VC_SPACE", "空格"], | |
// Alphanumeric Zone End | |
0x0e37: ["VC_PRINTSCREEN", "PrtSc"], | |
0x0046: ["VC_SCROLL_LOCK", "SCROLL LOCK"], | |
0x0e45: ["VC_PAUSE", "PAUSE"], | |
0x0e46: ["VC_LESSER_GREATER", "|"], // '<', ""], '>', ""], '|' on qwertz layout | |
// Edit Key Zone Begin | |
0x0e52: ["VC_INSERT", "INSERT"], | |
0x0e53: ["VC_DELETE", "DELETE"], | |
0x0e47: ["VC_HOME", "HOME"], | |
0x0e4f: ["VC_END", "END"], | |
0x0e49: ["VC_PAGE_UP", "PAGE UP"], | |
0x0e51: ["VC_PAGE_DOWN", "PAGE DOWN"], | |
/* https://github.com/univrsal/input-overlay/issues/174 */ | |
0xee52: ["VC_INSERT", "INSERT"], // 0x0e52 | |
0xee53: ["VC_DELETE", "DELETE"], // 0x0e53 | |
0xee47: ["VC_HOME", "HOME"], // 0x0e47 | |
0xee4f: ["VC_END", "END"], // 0x0e4f | |
0xee49: ["VC_PAGE_UP", "PAGE UP"], // 0x0e49 | |
0xee51: ["VC_PAGE_DOWN", "PAGE DOWN"], // 0x0e51 | |
// Edit Key Zone End | |
// Cursor Key Zone Begin | |
0x0e48: ["VC_UP", "↑"], | |
0x0e4b: ["VC_LEFT", "←"], | |
0x0e4c: ["VC_CLEAR", ""], | |
0x0e4d: ["VC_RIGHT", "→"], | |
0x0e50: ["VC_DOWN", "↓"], | |
/* https://github.com/univrsal/input-overlay/issues/174 */ | |
0xee48: ["VC_UP", "↑"], // 0x0e48 | |
0xee4b: ["VC_LEFT", "←"], // 0x0e4b | |
0xee4c: ["VC_CLEAR", ""], // 0x0e4c | |
0xee4d: ["VC_RIGHT", "→"], // 0x0e4d | |
0xee50: ["VC_DOWN", "↓"], // 0x0e50 | |
// Cursor Key Zone End | |
// Numeric Zone Begin | |
0x0045: ["VC_NUM_LOCK", "数字锁定"], | |
0x0e35: ["VC_KP_DIVIDE", "小键盘 /"], | |
0x0037: ["VC_KP_MULTIPLY", "小键盘 *"], | |
0x004a: ["VC_KP_SUBTRACT", "小键盘 -"], | |
0x0e0d: ["VC_KP_EQUALS", "小键盘 ="], | |
0x004e: ["VC_KP_ADD", "小键盘 +"], | |
0x0e1c: ["VC_KP_ENTER", "小键盘回车"], | |
0x0053: ["VC_KP_SEPARATOR", "小键盘 ."], | |
0x004f: ["VC_KP_1", "小键盘 1"], | |
0x0050: ["VC_KP_2", "小键盘 2"], | |
0x0051: ["VC_KP_3", "小键盘 3"], | |
0x004b: ["VC_KP_4", "小键盘 4"], | |
0x004c: ["VC_KP_5", "小键盘 5"], | |
0x004d: ["VC_KP_6", "小键盘 6"], | |
0x0047: ["VC_KP_7", "小键盘 7"], | |
0x0048: ["VC_KP_8", "小键盘 8"], | |
0x0049: ["VC_KP_9", "小键盘 9"], | |
0x0052: ["VC_KP_0", "小键盘 0"], | |
0xee00: ["VC_KP_END", ""], // VC_KP_1, ""], | |
0xee00: ["VC_KP_DOWN", ""], // VC_KP_2, ""], | |
0xee00: ["VC_KP_PAGE_DOWN", ""], // VC_KP_3, ""], | |
0xee00: ["VC_KP_LEFT", ""], // VC_KP_4, ""], | |
0xee00: ["VC_KP_CLEAR", ""], // VC_KP_5, ""], | |
0xee00: ["VC_KP_RIGHT", ""], // VC_KP_6, ""], | |
0xee00: ["VC_KP_HOME", ""], // VC_KP_7, ""], | |
0xee00: ["VC_KP_UP", ""], // VC_KP_8, ""], | |
0xee00: ["VC_KP_PAGE_UP", ""], // VC_KP_9, ""], | |
0xee00: ["VC_KP_INSERT", ""], // VC_KP_0, ""], | |
0xee00: ["VC_KP_DELETE", ""], // VC_KP_SEPARATOR, ""], | |
// Numeric Zone End | |
// Modifier and Control Keys Begin | |
0x002a: ["VC_SHIFT_L", "左 SHIFT"], | |
0x0036: ["VC_SHIFT_R", "右 SHIFT"], | |
0x001d: ["VC_CONTROL_L", "左 CTRL"], | |
0x0e1d: ["VC_CONTROL_R", "右 CTRL"], | |
0x0038: ["VC_ALT_L", "左 ALT"], // Option or Alt Key | |
0x0e38: ["VC_ALT_R", "右 ALT"], // Option or Alt Key | |
0x0e5b: ["VC_META_L", "WIN"], // Windows or Command Key | |
0x0e5c: ["VC_META_R", "WIN"], // Windows or Command Key | |
0x0e5d: ["VC_CONTEXT_MENU", "CONTEXT MENU"], | |
// Modifier and Control Keys End | |
// Media Control Keys Begin | |
0xe05e: ["VC_POWER", ""], | |
0xe05f: ["VC_SLEEP", ""], | |
0xe063: ["VC_WAKE", ""], | |
0xe022: ["VC_MEDIA_PLAY", ""], | |
0xe024: ["VC_MEDIA_STOP", ""], | |
0xe010: ["VC_MEDIA_PREVIOUS", ""], | |
0xe019: ["VC_MEDIA_NEXT", ""], | |
0xe06d: ["VC_MEDIA_SELECT", ""], | |
0xe02c: ["VC_MEDIA_EJECT", ""], | |
0xe020: ["VC_VOLUME_MUTE", ""], | |
0xe030: ["VC_VOLUME_UP", ""], | |
0xe02e: ["VC_VOLUME_DOWN", ""], | |
0xe06c: ["VC_APP_MAIL", ""], | |
0xe021: ["VC_APP_CALCULATOR", ""], | |
0xe03c: ["VC_APP_MUSIC", ""], | |
0xe064: ["VC_APP_PICTURES", ""], | |
0xe065: ["VC_BROWSER_SEARCH", ""], | |
0xe032: ["VC_BROWSER_HOME", ""], | |
0xe06a: ["VC_BROWSER_BACK", ""], | |
0xe069: ["VC_BROWSER_FORWARD", ""], | |
0xe068: ["VC_BROWSER_STOP", ""], | |
0xe067: ["VC_BROWSER_REFRESH", ""], | |
0xe066: ["VC_BROWSER_FAVORITES", ""], | |
// End Media Control Keys | |
// Begin Japanese Language Keys | |
0x0070: ["VC_KATAKANA", ""], | |
0x0073: ["VC_UNDERSCORE", ""], | |
0x0077: ["VC_FURIGANA", ""], | |
0x0079: ["VC_KANJI", ""], | |
0x007b: ["VC_HIRAGANA", ""], | |
0x007d: ["VC_YEN", ""], | |
0x007e: ["VC_KP_COMMA", ""], | |
// End Japanese Language Keys | |
// Begin Sun keyboards | |
0xff75: ["VC_SUN_HELP", "按下左键"], // REUSE EMPTY | |
0xff78: ["VC_SUN_STOP", "按下右键"], // REUSE EMPTY | |
0xff76: ["VC_SUN_PROPS", ""], | |
0xff77: ["VC_SUN_FRONT", ""], | |
0xff74: ["VC_SUN_OPEN", ""], | |
0xff7e: ["VC_SUN_FIND", ""], | |
0xff79: ["VC_SUN_AGAIN", ""], | |
0xff7a: ["VC_SUN_UNDO", ""], | |
0xff7c: ["VC_SUN_COPY", ""], | |
0xff7d: ["VC_SUN_INSERT", ""], | |
0xff7b: ["VC_SUN_CUT", ""], | |
// End Sun keyboards | |
0x0000: ["VC_UNDEFINED", ""], // KeyCode Unknown | |
0x0000: ["VC_UNDEFINED", ""], // KeyCode Unknown | |
0xffff: ["CHAR_UNDEFINED", ""], // CharCode Unknown | |
/* End Virtual Key Codes */ | |
/* Begin Virtual Modifier Masks */ | |
// MASK_SHIFT_L 1 << 0 | |
// MASK_CTRL_L 1 << 1 | |
// MASK_META_L 1 << 2 | |
// MASK_ALT_L 1 << 3 | |
// MASK_SHIFT_R 1 << 4 | |
// MASK_CTRL_R 1 << 5 | |
// MASK_META_R 1 << 6 | |
// MASK_ALT_R 1 << 7 | |
// MASK_SHIFT MASK_SHIFT_L | MASK_SHIFT_R | |
// MASK_CTRL MASK_CTRL_L | MASK_CTRL_R | |
// MASK_META MASK_META_L | MASK_META_R | |
// MASK_ALT MASK_ALT_L | MASK_ALT_R | |
// MASK_BUTTON1 1 << 8 | |
// MASK_BUTTON2 1 << 9 | |
// MASK_BUTTON3 1 << 10 | |
// MASK_BUTTON4 1 << 11 | |
// MASK_BUTTON5 1 << 12 | |
// MASK_NUM_LOCK 1 << 13 | |
// MASK_CAPS_LOCK 1 << 14 | |
// MASK_SCROLL_LOCK 1 << 15 | |
/* End Virtual Modifier Masks */ | |
}; | |
/** | |
* This will either return an HTML string (icon) | |
* Or a plain string (libuiohook key name) | |
* | |
* @param {string} keycode - keycode from libuiohook | |
* | |
* @returns {string} Inline innerHTML equivalent of key | |
*/ | |
function getKeyHTML(keycode) { | |
var key = KEYCODES[parseInt(keycode)]; | |
if (!!key) { | |
var icon = KEYICONS[parseInt(keycode)]; | |
if (!!icon) { | |
return icon.cloneNode(true).outerHTML; | |
} else { | |
// return alias if present | |
return key[1] !== "" ? key[1] : key[0]; | |
} | |
} else { | |
return ""; | |
} | |
} | |
// #region Keys with Icons | |
/* Init SVG Icons */ | |
document | |
.querySelectorAll("#icons-container > svg") | |
.forEach((i) => i.classList.add("icon-sm")); | |
document | |
.querySelectorAll("#icons-container > svg > path") | |
.forEach((p) => p.setAttribute("fill", "currentColor")); | |
/** | |
* For Keys to replace with Icons | |
* Key: libuihook keycode | |
* Value: <svg> icon element | |
*/ | |
var KEYICONS = { | |
0x0e5b: document.getElementById("SVG_VC_META"), // VC_META_L Windows or Command Key | |
0x0e5c: document.getElementById("SVG_VC_META"), // VC_META_R Windows or Command Key | |
// Arrow Keys | |
0x0e48: document.getElementById("SVG_VC_UP"), // ARROW UP | |
0x0e4b: document.getElementById("SVG_VC_LEFT"), // ARROW LEFT | |
0x0e4d: document.getElementById("SVG_VC_RIGHT"), // ARROW RIGHT | |
0x0e50: document.getElementById("SVG_VC_DOWN"), // ARROW DOWN | |
/* https://github.com/univrsal/input-overlay/issues/174 */ | |
0xee48: document.getElementById("SVG_VC_UP"), // ARROW UP | |
0xee4b: document.getElementById("SVG_VC_LEFT"), // ARROW LEFT | |
0xee4d: document.getElementById("SVG_VC_RIGHT"), // ARROW RIGHT | |
0xee50: document.getElementById("SVG_VC_DOWN"), // ARROW DOWN | |
0x001c: document.getElementById("SVG_VC_ENTER"), | |
}; | |
// #endregion | |
// #region DOM Utils | |
/** | |
* Gets a {Set} of keycodes, wraps each item in span.key, and joins them by a + (separator) | |
* | |
* @returns {HTMLElement} <p> element of key combination | |
*/ | |
function getKeyCombinationElement(setOfKeycodes = new Set()) { | |
try { | |
var innerHTMLofKeys = Array.from(setOfKeycodes) | |
.map((keycode) => getKeyHTML(keycode)) | |
// Filter out non-existing keys in KEYCODES | |
.filter((html) => html !== ""); | |
// console.log(innerHTMLofKeys) | |
// Build innerHTMl for the key combination | |
var innerHTMLOfKeyCombination = innerHTMLofKeys | |
.map( | |
(innerHTML) => | |
createElementWithClass("span", innerHTML, ["key"]).outerHTML | |
) | |
.join( | |
createElementWithClass("span", SEPARATOR, ["separator"]).outerHTML | |
); | |
return createElementWithClass("p", innerHTMLOfKeyCombination, [ | |
"key-combination", | |
]); | |
} catch (e) { | |
console.error(e); | |
return ""; | |
} | |
} | |
/** | |
* Wraps an HTML string of a key with span | |
* | |
* @returns {HTMLElement} HTML Element created with classes | |
*/ | |
function createElementWithClass(element, innerHTML = "", classList = []) { | |
var el = document.createElement(element); | |
el.innerHTML = innerHTML; | |
el.classList.add(...classList); | |
return el; | |
} | |
// #endregion | |
// #region ----- YOU CAN CHANGE THESE VALUES ----- | |
/** | |
* Max count of history shown. Lower = better performance. | |
* @type {number} | |
*/ | |
var HISTORY_MAX = 4; | |
/** | |
* Enable / Disable timeout for key combinations | |
* @type {boolean} | |
*/ | |
var HISTORY_TIMEOUT_ACTIVE = true; | |
/** | |
* Time delay in ms before the key is hidden. | |
* @type {number} | |
*/ | |
var HISTORY_TIMEOUT = 5000; | |
/** | |
* Separator between keys | |
* @type {string} | |
*/ | |
var SEPARATOR = "+"; | |
// #endregion | |
// History | |
var _historyDiv = document.getElementById("history"); | |
var _historyCurrentlyPressed = new Set(); | |
var _pressedLength = new Array(); | |
var _isHistoryPressing = false; | |
function onKeyEvent(data) { | |
if ( | |
data.event_type.startsWith("mouse") || | |
data.event_type === "key_typed" | |
) | |
return; | |
// console.log(data); | |
// Update Set to current key combination | |
if (data.event_type === "key_pressed") { | |
_historyCurrentlyPressed.add(data.keycode); | |
_isHistoryPressing = true; | |
} else if (data.event_type === "key_released") { | |
_historyCurrentlyPressed.delete(data.keycode); | |
_isHistoryPressing = false; | |
} | |
// console.log(_historyCurrentlyPressed); | |
updateUI(); | |
} | |
function onKeyAndClickEvent(data) { | |
if ( | |
data.event_type === "key_typed" | |
) | |
return; | |
var _isValidPress = false; | |
// console.log(data); | |
// Update Set to current key combination | |
if (data.event_type === "mouse_pressed" || data.event_type === "key_pressed") { | |
_isValidPress = true | |
if (data.event_type.startsWith("mouse")) { | |
if (data.event_type === "mouse_pressed"){ | |
if (data.button === 1){ | |
_historyCurrentlyPressed.add(65397); // mouse press code | |
} else if (data.button === 2) { | |
_historyCurrentlyPressed.add(65400); // mouse press code | |
} | |
} | |
} else { | |
_historyCurrentlyPressed.add(data.keycode); | |
} | |
_pressedLength.push(_historyCurrentlyPressed.size) | |
_isHistoryPressing = true; | |
} else if (data.event_type === "key_released") { | |
_historyCurrentlyPressed.delete(data.keycode); | |
_isHistoryPressing = false; | |
} else if (data.event_type === "mouse_clicked" || data.event_type === "mouse_released") { | |
if (data.button === 1){ | |
_historyCurrentlyPressed.delete(65397); | |
} else if (data.button === 2) { | |
_historyCurrentlyPressed.delete(65400); | |
} | |
_isHistoryPressing = false; | |
} | |
// console.log(_historyCurrentlyPressed); | |
updateUI(); | |
if (_isValidPress && _pressedLength.length >= 30) { | |
let sum = 0; | |
for(let i = 0; i < _pressedLength.length; i++){ | |
sum += parseInt( _pressedLength[i], 10 ); //don't forget to add the base | |
} | |
let avg = sum/_pressedLength.length; | |
//console.log(avg); | |
if (avg > 1.67 || _pressedLength.length >= 100) { | |
//console.log("RESET at " + avg + " with Array length" + _pressedLength.length); | |
_historyCurrentlyPressed = new Set(); // reset history | |
_pressedLength = new Array(); | |
} | |
} | |
} | |
function updateUI() { | |
var lastChildInnerHTML = | |
_historyDiv.lastElementChild == null | |
? "" | |
: _historyDiv.lastElementChild.innerHTML; | |
var isLastChildEmpty = lastChildInnerHTML === ""; | |
if (_isHistoryPressing) { | |
// If starting key combination, set last item text | |
if (_historyDiv.childElementCount > 0) { | |
_historyDiv.lastElementChild.innerHTML = getKeyCombinationElement( | |
_historyCurrentlyPressed | |
).innerHTML; | |
} | |
// OR add an element if this is first combination | |
else { | |
_historyDiv.appendChild( | |
getKeyCombinationElement(_historyCurrentlyPressed) | |
); | |
} | |
} | |
// If done pressing key combination, | |
else { | |
if (!isLastChildEmpty) { | |
if (HISTORY_TIMEOUT_ACTIVE) { | |
// Add removing class of last key combination | |
var elementToHide = _historyDiv.lastElementChild; | |
setTimeout(() => { | |
elementToHide.classList.add("hidden"); | |
}, HISTORY_TIMEOUT); | |
} | |
// Then add a empty slot | |
_historyDiv.appendChild(getKeyCombinationElement()); | |
} | |
} | |
// Remove first element | |
if (_historyDiv.children.length > HISTORY_MAX) | |
_historyDiv.firstChild.remove(); | |
// Scroll down | |
scrollTo({ | |
top: document.body.scrollHeight, | |
}); | |
} | |
function on_data(e) { | |
// Since data is in string, parse first | |
var data = JSON.parse(e.data); | |
// Show for browser source | |
// onKeyEvent(data); | |
onKeyAndClickEvent(data); | |
} | |
function start_websocket() { | |
var ws = new WebSocket("ws://localhost:16899/"); | |
ws.onmessage = on_data; | |
ws.onerror = (e) => { | |
console.log("WebSocket error: "); | |
console.error(e); | |
}; | |
ws.onclose = () => { | |
// connection closed, discard old websocket and create a new one in 5s | |
ws = null; | |
setTimeout(start_websocket, 2000); | |
}; | |
} | |
start_websocket(); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment