Keyboard.html 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <style data-theme="core" type="text/css">
  6. :root {
  7. --keyMargin: 1px;
  8. --keyWidth: calc(45px + var(--keyMargin) * 2);
  9. }
  10. html, body {
  11. margin: 0; padding: 0;
  12. color: black;
  13. user-select: none;
  14. font-size: 25px;
  15. }
  16. .keyHolder {
  17. margin: 5px;
  18. display: inline-block;
  19. }
  20. .key, .noShow {
  21. display: inline-block;
  22. box-sizing: border-box;
  23. border: 1px solid black;
  24. border-radius: 4px;
  25. background: rgba(255, 255, 255, .7);
  26. text-align: center;
  27. cursor: pointer;
  28. padding-top: 10px;
  29. vertical-align: middle;
  30. margin: var(--keyMargin);
  31. width: calc(var(--keyWidth) - var(--keyMargin) * 2);
  32. height: calc(var(--keyWidth) - var(--keyMargin) * 2);
  33. }
  34. .noShow {
  35. border: none;
  36. background: transparent !important;
  37. cursor: inherit;
  38. }
  39. .key:hover {
  40. background: #EEE;
  41. }
  42. .key.pressed, .key[data-pressed=true] {
  43. background: #555;
  44. }
  45. .key.s1x1_25 { width: calc(var(--keyWidth) * 1.25 - var(--keyMargin) * 2); }
  46. .key.s1x1_5 { width: calc(var(--keyWidth) * 1.5 - var(--keyMargin) * 2); }
  47. .key.s1x2 { width: calc(var(--keyWidth) * 2 - var(--keyMargin) * 2); }
  48. .key.s1x1_75 { width: calc(var(--keyWidth) * 1.75 - var(--keyMargin) * 2); }
  49. .key.s1x2_25 { width: calc(var(--keyWidth) * 2.25 - var(--keyMargin) * 2); }
  50. .key.s1x2_75 { width: calc(var(--keyWidth) * 2.75 - var(--keyMargin) * 2); }
  51. .key.s1x3_75 { width: calc(var(--keyWidth) * 3.75 - var(--keyMargin) * 2); }
  52. .key.s1x4_75 { width: calc(var(--keyWidth) * 4.75 - var(--keyMargin) * 2); }
  53. .key.s1x6_5 { width: calc(var(--keyWidth) * 6.5 - var(--keyMargin) * 2); }
  54. .key.s2x1 {
  55. height: calc(var(--keyWidth) * 2 - var(--keyMargin) * 2);
  56. float: right;
  57. padding-top: 32px;
  58. }
  59. .smallText {
  60. font-size: 50%;
  61. padding-top: 15px;
  62. }
  63. </style>
  64. <style data-theme="0" type="text/css">
  65. .key {
  66. border-radius: 6px;
  67. }
  68. </style>
  69. <style data-theme="1" type="text/css">
  70. body {
  71. text-transform: uppercase;
  72. color: white;
  73. font-size: 20px;
  74. font-family: monospace;
  75. }
  76. .key {
  77. border-color: white;
  78. background: rgba(0, 0, 0, .6);
  79. padding-top: 10px;
  80. border-radius: 0;
  81. }
  82. .key:hover {
  83. background: #333;
  84. }
  85. .key.pressed, .key[data-pressed=true] {
  86. background: #CCC;
  87. position: relative;
  88. top: 1px; left: 1px;
  89. }
  90. .smallText {
  91. padding-top: 16px;
  92. }
  93. .s2x1 { padding-top: 32px; }
  94. .s2x1.kpEnter { padding-top: 62px; }
  95. </style>
  96. <style data-theme="2" type="text/css">
  97. :root {
  98. --keyMargin: 1px;
  99. --keyWidth: calc(46px + var(--keyMargin) * 2);
  100. }
  101. body {
  102. font-family: sans-serif;
  103. }
  104. .keyHolder {
  105. background: white;
  106. margin: 1px;
  107. padding: 4px;
  108. border-radius: 7px;
  109. }
  110. .key {
  111. padding-top: 9px;
  112. border-color: #777;
  113. }
  114. .key:hover {
  115. background: #FFFAE2;
  116. }
  117. .key.pressed, .key[data-pressed=true] {
  118. background: rgba(146, 190, 255, 1);
  119. position: relative;
  120. top: 1px; left: 1px;
  121. }
  122. .smallText {
  123. padding-top: 16px;
  124. }
  125. </style>
  126. <style data-theme="3" type="text/css">
  127. :root {
  128. --keyMargin: 2px;
  129. --keyWidth: calc(43px + var(--keyMargin) * 2);
  130. }
  131. body {
  132. /*text-transform: uppercase;*/
  133. color: #FFF;
  134. font-size: 20px;
  135. font-family: monospace;
  136. }
  137. .key {
  138. border-color: #0F0;
  139. background: rgba(0, 0, 0, 1);
  140. padding-top: 10px;
  141. box-shadow: 0 0 10px #0F0;
  142. }
  143. .key:hover {
  144. background: #000;
  145. border-width: 2px;
  146. }
  147. .key.pressed, .key[data-pressed=true] {
  148. background: #0F0;
  149. color: black;
  150. }
  151. .smallText {
  152. padding-top: 16px;
  153. }
  154. .s2x1 { padding-top: 32px; }
  155. </style>
  156. </head>
  157. <body>
  158. <div id="mainKeys" class="keyHolder"></div>
  159. <div id="navKeys" class="keyHolder"></div>
  160. <div id="numberKeys" class="keyHolder"></div>
  161. <script type="application/javascript">
  162. //API funcs:
  163. function textTyped(text) { console.log(`Typed: ${text} (u0x${text.charCodeAt(0).toString(16)})`)};
  164. function commandEntered(action, shiftPressed) { console.log(`Command: ${action} Shift: ${shiftPressed}`)};
  165. function capsLockPressed() {
  166. shiftOn = capsLockOn = !capsLockOn;
  167. setShifted(shiftOn);
  168. }
  169. function shiftPressed() {
  170. capsLockOn = false;
  171. shiftOn = !shiftOn;
  172. setShifted(shiftOn);
  173. }
  174. var allKeys = [];
  175. var shiftOn = false;
  176. var capsLockOn = false;
  177. function generateKeys(element, keys) {
  178. var parent = document.getElementById(element);
  179. for (var i = 0; i < keys.length; i++) {
  180. for (var j = 0; j < keys[i].length; j++) {
  181. var keyInfo = keys[i][j];
  182. if (typeof keyInfo == "string") {
  183. keyInfo = {
  184. text: keyInfo[0],
  185. upperText: keyInfo[1] || keyInfo[0].toUpperCase(),
  186. };
  187. }
  188. keyInfo.label = keyInfo.label || keyInfo.text || '';
  189. keyInfo.upperLabel = keyInfo.upperText ? keyInfo.upperText : keyInfo.label;
  190. keyInfo.size = keyInfo.size || "1x1";
  191. keyInfo.smallText = keyInfo.smallText === undefined ? keyInfo.label.length > 1 : keyInfo.smallText;
  192. allKeys.push(keyInfo);
  193. var keyEl = document.createElement("span");
  194. keyEl.className = `${keyInfo.noShow ? "noShow" : "key"} s${keyInfo.size} ${keyInfo.smallText ? "smallText" : ""}`;
  195. keyEl.setAttribute("data-keyId", allKeys.length - 1);
  196. keyEl.textContent = keyInfo.label;
  197. parent.appendChild(keyEl);
  198. if (keyInfo.title) keyEl.title = keyInfo.title;
  199. keyInfo.el = keyEl;
  200. keyInfo.baseClass = keyEl.className;
  201. }
  202. var br = document.createElement("br");
  203. parent.appendChild(br);
  204. }
  205. }
  206. function setShifted(shifted) {
  207. for (var i = 0; i < allKeys.length; i++) {
  208. allKeys[i].el.textContent = shifted ? allKeys[i].upperLabel || allKeys[i].label : allKeys[i].label;
  209. if (allKeys[i].isPressed) {
  210. allKeys[i].el.setAttribute("data-pressed", allKeys[i].isPressed());
  211. }
  212. }
  213. }
  214. addEventListener("mousedown", ev => {
  215. var keyId = ev.target.getAttribute("data-keyId");
  216. if (keyId === null) return;
  217. var keyInfo = allKeys[keyId];
  218. var press = () => {
  219. ev.preventDefault();
  220. ev.target.className += " pressed";
  221. setTimeout(() => ev.target.className = keyInfo.baseClass, 50);
  222. };
  223. if (keyInfo.action) {
  224. keyInfo.action();
  225. press();
  226. return;
  227. }
  228. if (keyInfo.command) {
  229. commandEntered(keyInfo.command, shiftOn);
  230. press();
  231. return;
  232. }
  233. if (keyInfo.text) {
  234. var text = shiftOn ? keyInfo.upperText || keyInfo.text : keyInfo.text;
  235. textTyped(text);
  236. press();
  237. if (shiftOn && !capsLockOn) {
  238. shiftOn = false;
  239. setShifted(shiftOn);
  240. }
  241. return;
  242. }
  243. }, true);
  244. var currentScheme = 0;
  245. function cycleColorScheme() {
  246. currentScheme = (currentScheme + 1) % 4;
  247. setColorScheme(currentScheme);
  248. }
  249. function setColorScheme(index) {
  250. for (var el of document.getElementsByTagName("style")) {
  251. if (el.getAttribute("data-theme") == "core") continue;
  252. if (el.getAttribute("data-theme") == index) el.disabled = false;
  253. else el.disabled = true;
  254. }
  255. currentScheme = +index;
  256. localStorage.colorScheme = index;
  257. }
  258. setColorScheme(localStorage.colorScheme == undefined ? 2 : localStorage.colorScheme);
  259. var mainKeys = [
  260. ["`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+", {label: "←", command: "backspace", size: "1x2"}],
  261. [
  262. {label: "Tab", text: "\t", size: "1x1_5", smallText: false},
  263. "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[{", "]}",
  264. {text: "\\", upperText: "|", size: "1x1_5"},
  265. ], [
  266. {label: "Caps\nLock", size: "1x1_75 capsLock", action: capsLockPressed, isPressed: () => capsLockOn},
  267. "a", "s", "d", "f", "g", "h", "j", "k", "l", ";:", "'\"",
  268. {label: "↵", text: "\n", size: "1x2_25"},
  269. ], [
  270. {label: "Shift", action: shiftPressed, size: "1x2_25", isPressed: () => shiftOn, smallText: false},
  271. "z", "x", "c", "v", "b", "n", "m", ",<", ".>", "/?",
  272. {label: "Shift", action: shiftPressed, size: "1x2_75", isPressed: () => shiftOn, smallText: false},
  273. ],
  274. [
  275. // {label: "", size: "1x3_75", noShow: true},
  276. {label: "Sel All", size: "1x1_25", command: "selectAll"},
  277. {label: "↶", size: "1x1_25", command: "undo", title: "Undo"},
  278. {label: "↷", size: "1x1_25", command: "redo", title: "Redo"},
  279. // {label: "Cut", size: "1x1_25", command: "cut"},
  280. // {label: "Copy", size: "1x1_25", command: "copy"},
  281. // {label: "Paste", size: "1x1_25", command: "paste"},
  282. {label: "", size: "1x6_5", text: " "},//space
  283. // {label: "Select All", size: "1x1_75", command: "selectAll"},
  284. // {label: "↶", size: "1x1_5", command: "undo", title: "Undo"},
  285. // {label: "↷", size: "1x1_5", command: "redo", title: "Redo"},
  286. {label: "Cut", size: "1x1_5", command: "cut"},
  287. {label: "Copy", size: "1x1_75", command: "copy"},
  288. {label: "Paste", size: "1x1_5", command: "paste"},
  289. // {label: "", size: "1x4_75", noShow: true},
  290. ]
  291. ];
  292. var navKeys = [
  293. [{label: "Insert", command: "insert"}, {label: "Home", command: "home"}, {label: "PgUp", command: "pageUp"}],
  294. [{label: "Delete", command: "delete"}, {label: "End", command: "end"}, {label: "PgDn", command: "pageDown"}],
  295. [{noShow: true}],
  296. [
  297. {label: "⇤", command: "wordLeft", title: "Move one word left"},
  298. {label: "↑", command: "up"},
  299. {label: "⇥", command: "wordRight", title: "Move one word right"}
  300. ],
  301. [{label: "←", command: "left"}, {label: "↓", command: "down"}, {label: "→", command: "right"}],
  302. ];
  303. var numberKeys = [
  304. [
  305. // {noShow: true},
  306. {label: "✩", smallText: true, action: cycleColorScheme},
  307. "/", "*", "-",
  308. ],
  309. ["7", "8", "9", {text: "+", size: "2x1"}],
  310. ["4", "5", "6"],
  311. ["1", "2", "3", {label: "↵", text: "\n", size: "2x1 kpEnter"}],
  312. [{text: "0", size: "1x2"}, "."],
  313. ];
  314. generateKeys("mainKeys", mainKeys);
  315. generateKeys("navKeys", navKeys);
  316. generateKeys("numberKeys", numberKeys);
  317. </script>
  318. </body>
  319. </html>