371 lines
9.6 KiB
HTML
371 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<style data-theme="core" type="text/css">
|
|
:root {
|
|
--keyMargin: 1px;
|
|
--keyWidth: calc(45px + var(--keyMargin) * 2);
|
|
}
|
|
|
|
html, body {
|
|
margin: 0; padding: 0;
|
|
color: black;
|
|
user-select: none;
|
|
font-size: 25px;
|
|
}
|
|
|
|
.keyHolder {
|
|
margin: 5px;
|
|
display: inline-block;
|
|
}
|
|
|
|
.key, .noShow {
|
|
display: inline-block;
|
|
box-sizing: border-box;
|
|
border: 1px solid black;
|
|
border-radius: 4px;
|
|
background: rgba(255, 255, 255, .7);
|
|
text-align: center;
|
|
cursor: pointer;
|
|
padding-top: 10px;
|
|
vertical-align: middle;
|
|
|
|
margin: var(--keyMargin);
|
|
width: calc(var(--keyWidth) - var(--keyMargin) * 2);
|
|
height: calc(var(--keyWidth) - var(--keyMargin) * 2);
|
|
}
|
|
|
|
.noShow {
|
|
border: none;
|
|
background: transparent !important;
|
|
cursor: inherit;
|
|
}
|
|
|
|
.key:hover {
|
|
background: #EEE;
|
|
}
|
|
|
|
.key.pressed, .key[data-pressed=true] {
|
|
background: #555;
|
|
}
|
|
|
|
.key.s1x1_25 { width: calc(var(--keyWidth) * 1.25 - var(--keyMargin) * 2); }
|
|
.key.s1x1_5 { width: calc(var(--keyWidth) * 1.5 - var(--keyMargin) * 2); }
|
|
.key.s1x2 { width: calc(var(--keyWidth) * 2 - var(--keyMargin) * 2); }
|
|
.key.s1x1_75 { width: calc(var(--keyWidth) * 1.75 - var(--keyMargin) * 2); }
|
|
.key.s1x2_25 { width: calc(var(--keyWidth) * 2.25 - var(--keyMargin) * 2); }
|
|
.key.s1x2_75 { width: calc(var(--keyWidth) * 2.75 - var(--keyMargin) * 2); }
|
|
.key.s1x3_75 { width: calc(var(--keyWidth) * 3.75 - var(--keyMargin) * 2); }
|
|
.key.s1x4_75 { width: calc(var(--keyWidth) * 4.75 - var(--keyMargin) * 2); }
|
|
.key.s1x6_5 { width: calc(var(--keyWidth) * 6.5 - var(--keyMargin) * 2); }
|
|
|
|
.key.s2x1 {
|
|
height: calc(var(--keyWidth) * 2 - var(--keyMargin) * 2);
|
|
float: right;
|
|
padding-top: 32px;
|
|
}
|
|
|
|
.smallText {
|
|
font-size: 50%;
|
|
padding-top: 15px;
|
|
}
|
|
</style>
|
|
<style data-theme="0" type="text/css">
|
|
.key {
|
|
border-radius: 6px;
|
|
}
|
|
</style>
|
|
<style data-theme="1" type="text/css">
|
|
body {
|
|
text-transform: uppercase;
|
|
color: white;
|
|
font-size: 20px;
|
|
font-family: monospace;
|
|
}
|
|
.key {
|
|
border-color: white;
|
|
background: rgba(0, 0, 0, .6);
|
|
padding-top: 10px;
|
|
border-radius: 0;
|
|
}
|
|
.key:hover {
|
|
background: #333;
|
|
}
|
|
.key.pressed, .key[data-pressed=true] {
|
|
background: #CCC;
|
|
position: relative;
|
|
top: 1px; left: 1px;
|
|
|
|
}
|
|
.smallText {
|
|
padding-top: 16px;
|
|
}
|
|
.s2x1 { padding-top: 32px; }
|
|
.s2x1.kpEnter { padding-top: 62px; }
|
|
</style>
|
|
<style data-theme="2" type="text/css">
|
|
:root {
|
|
--keyMargin: 1px;
|
|
--keyWidth: calc(46px + var(--keyMargin) * 2);
|
|
}
|
|
body {
|
|
font-family: sans-serif;
|
|
}
|
|
.keyHolder {
|
|
background: white;
|
|
margin: 1px;
|
|
padding: 4px;
|
|
border-radius: 7px;
|
|
}
|
|
.key {
|
|
padding-top: 9px;
|
|
border-color: #777;
|
|
}
|
|
.key:hover {
|
|
background: #FFFAE2;
|
|
}
|
|
.key.pressed, .key[data-pressed=true] {
|
|
background: rgba(146, 190, 255, 1);
|
|
position: relative;
|
|
top: 1px; left: 1px;
|
|
}
|
|
.smallText {
|
|
padding-top: 16px;
|
|
}
|
|
</style>
|
|
<style data-theme="3" type="text/css">
|
|
:root {
|
|
--keyMargin: 2px;
|
|
--keyWidth: calc(43px + var(--keyMargin) * 2);
|
|
}
|
|
body {
|
|
/*text-transform: uppercase;*/
|
|
color: #FFF;
|
|
font-size: 20px;
|
|
font-family: monospace;
|
|
}
|
|
.key {
|
|
border-color: #0F0;
|
|
background: rgba(0, 0, 0, 1);
|
|
padding-top: 10px;
|
|
box-shadow: 0 0 10px #0F0;
|
|
}
|
|
.key:hover {
|
|
background: #000;
|
|
|
|
border-width: 2px;
|
|
|
|
}
|
|
.key.pressed, .key[data-pressed=true] {
|
|
background: #0F0;
|
|
color: black;
|
|
}
|
|
.smallText {
|
|
padding-top: 16px;
|
|
}
|
|
.s2x1 { padding-top: 32px; }
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div id="mainKeys" class="keyHolder"></div>
|
|
<div id="navKeys" class="keyHolder"></div>
|
|
<div id="numberKeys" class="keyHolder"></div>
|
|
|
|
<script type="application/javascript">
|
|
//API funcs:
|
|
function textTyped(text) { console.log(`Typed: ${text} (u0x${text.charCodeAt(0).toString(16)})`)};
|
|
function commandEntered(action, shiftPressed) { console.log(`Command: ${action} Shift: ${shiftPressed}`)};
|
|
|
|
|
|
|
|
function capsLockPressed() {
|
|
shiftOn = capsLockOn = !capsLockOn;
|
|
setShifted(shiftOn);
|
|
}
|
|
|
|
function shiftPressed() {
|
|
capsLockOn = false;
|
|
shiftOn = !shiftOn;
|
|
setShifted(shiftOn);
|
|
}
|
|
|
|
var allKeys = [];
|
|
var shiftOn = false;
|
|
var capsLockOn = false;
|
|
|
|
function generateKeys(element, keys) {
|
|
var parent = document.getElementById(element);
|
|
|
|
for (var i = 0; i < keys.length; i++) {
|
|
for (var j = 0; j < keys[i].length; j++) {
|
|
var keyInfo = keys[i][j];
|
|
|
|
if (typeof keyInfo == "string") {
|
|
keyInfo = {
|
|
text: keyInfo[0],
|
|
upperText: keyInfo[1] || keyInfo[0].toUpperCase(),
|
|
};
|
|
}
|
|
keyInfo.label = keyInfo.label || keyInfo.text || '';
|
|
keyInfo.upperLabel = keyInfo.upperText ? keyInfo.upperText : keyInfo.label;
|
|
keyInfo.size = keyInfo.size || "1x1";
|
|
keyInfo.smallText = keyInfo.smallText === undefined ? keyInfo.label.length > 1 : keyInfo.smallText;
|
|
|
|
allKeys.push(keyInfo);
|
|
|
|
var keyEl = document.createElement("span");
|
|
keyEl.className = `${keyInfo.noShow ? "noShow" : "key"} s${keyInfo.size} ${keyInfo.smallText ? "smallText" : ""}`;
|
|
keyEl.setAttribute("data-keyId", allKeys.length - 1);
|
|
keyEl.textContent = keyInfo.label;
|
|
parent.appendChild(keyEl);
|
|
if (keyInfo.title) keyEl.title = keyInfo.title;
|
|
|
|
keyInfo.el = keyEl;
|
|
keyInfo.baseClass = keyEl.className;
|
|
}
|
|
|
|
var br = document.createElement("br");
|
|
parent.appendChild(br);
|
|
}
|
|
}
|
|
|
|
function setShifted(shifted) {
|
|
for (var i = 0; i < allKeys.length; i++) {
|
|
allKeys[i].el.textContent = shifted ? allKeys[i].upperLabel || allKeys[i].label : allKeys[i].label;
|
|
if (allKeys[i].isPressed) {
|
|
allKeys[i].el.setAttribute("data-pressed", allKeys[i].isPressed());
|
|
}
|
|
}
|
|
}
|
|
|
|
addEventListener("mousedown", ev => {
|
|
var keyId = ev.target.getAttribute("data-keyId");
|
|
if (keyId === null) return;
|
|
|
|
var keyInfo = allKeys[keyId];
|
|
|
|
var press = () => {
|
|
ev.preventDefault();
|
|
ev.target.className += " pressed";
|
|
setTimeout(() => ev.target.className = keyInfo.baseClass, 50);
|
|
};
|
|
|
|
if (keyInfo.action) {
|
|
keyInfo.action();
|
|
press();
|
|
return;
|
|
}
|
|
|
|
if (keyInfo.command) {
|
|
commandEntered(keyInfo.command, shiftOn);
|
|
press();
|
|
return;
|
|
}
|
|
|
|
if (keyInfo.text) {
|
|
var text = shiftOn ? keyInfo.upperText || keyInfo.text : keyInfo.text;
|
|
|
|
textTyped(text);
|
|
press();
|
|
|
|
if (shiftOn && !capsLockOn) {
|
|
shiftOn = false;
|
|
setShifted(shiftOn);
|
|
}
|
|
return;
|
|
}
|
|
|
|
}, true);
|
|
|
|
var currentScheme = 0;
|
|
function cycleColorScheme() {
|
|
currentScheme = (currentScheme + 1) % 4;
|
|
setColorScheme(currentScheme);
|
|
}
|
|
|
|
function setColorScheme(index) {
|
|
for (var el of document.getElementsByTagName("style")) {
|
|
if (el.getAttribute("data-theme") == "core") continue;
|
|
if (el.getAttribute("data-theme") == index) el.disabled = false;
|
|
else el.disabled = true;
|
|
}
|
|
currentScheme = +index;
|
|
localStorage.colorScheme = index;
|
|
}
|
|
|
|
setColorScheme(localStorage.colorScheme == undefined ? 2 : localStorage.colorScheme);
|
|
|
|
|
|
var mainKeys = [
|
|
["`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+", {label: "←", command: "backspace", size: "1x2"}],
|
|
[
|
|
{label: "Tab", text: "\t", size: "1x1_5", smallText: false},
|
|
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[{", "]}",
|
|
{text: "\\", upperText: "|", size: "1x1_5"},
|
|
], [
|
|
{label: "Caps\nLock", size: "1x1_75 capsLock", action: capsLockPressed, isPressed: () => capsLockOn},
|
|
"a", "s", "d", "f", "g", "h", "j", "k", "l", ";:", "'\"",
|
|
{label: "↵", text: "\n", size: "1x2_25"},
|
|
], [
|
|
{label: "Shift", action: shiftPressed, size: "1x2_25", isPressed: () => shiftOn, smallText: false},
|
|
"z", "x", "c", "v", "b", "n", "m", ",<", ".>", "/?",
|
|
{label: "Shift", action: shiftPressed, size: "1x2_75", isPressed: () => shiftOn, smallText: false},
|
|
],
|
|
[
|
|
// {label: "", size: "1x3_75", noShow: true},
|
|
|
|
{label: "Sel All", size: "1x1_25", command: "selectAll"},
|
|
{label: "↶", size: "1x1_25", command: "undo", title: "Undo"},
|
|
{label: "↷", size: "1x1_25", command: "redo", title: "Redo"},
|
|
|
|
// {label: "Cut", size: "1x1_25", command: "cut"},
|
|
// {label: "Copy", size: "1x1_25", command: "copy"},
|
|
// {label: "Paste", size: "1x1_25", command: "paste"},
|
|
|
|
{label: "", size: "1x6_5", text: " "},//space
|
|
|
|
// {label: "Select All", size: "1x1_75", command: "selectAll"},
|
|
// {label: "↶", size: "1x1_5", command: "undo", title: "Undo"},
|
|
// {label: "↷", size: "1x1_5", command: "redo", title: "Redo"},
|
|
|
|
{label: "Cut", size: "1x1_5", command: "cut"},
|
|
{label: "Copy", size: "1x1_75", command: "copy"},
|
|
{label: "Paste", size: "1x1_5", command: "paste"},
|
|
|
|
// {label: "", size: "1x4_75", noShow: true},
|
|
]
|
|
];
|
|
|
|
var navKeys = [
|
|
[{label: "Insert", command: "insert"}, {label: "Home", command: "home"}, {label: "PgUp", command: "pageUp"}],
|
|
[{label: "Delete", command: "delete"}, {label: "End", command: "end"}, {label: "PgDn", command: "pageDown"}],
|
|
[{noShow: true}],
|
|
[
|
|
{label: "⇤", command: "wordLeft", title: "Move one word left"},
|
|
{label: "↑", command: "up"},
|
|
{label: "⇥", command: "wordRight", title: "Move one word right"}
|
|
],
|
|
[{label: "←", command: "left"}, {label: "↓", command: "down"}, {label: "→", command: "right"}],
|
|
];
|
|
|
|
var numberKeys = [
|
|
[
|
|
// {noShow: true},
|
|
{label: "✩", smallText: true, action: cycleColorScheme},
|
|
"/", "*", "-",
|
|
],
|
|
["7", "8", "9", {text: "+", size: "2x1"}],
|
|
["4", "5", "6"],
|
|
["1", "2", "3", {label: "↵", text: "\n", size: "2x1 kpEnter"}],
|
|
[{text: "0", size: "1x2"}, "."],
|
|
];
|
|
|
|
generateKeys("mainKeys", mainKeys);
|
|
generateKeys("navKeys", navKeys);
|
|
generateKeys("numberKeys", numberKeys);
|
|
|
|
</script>
|
|
</body>
|
|
</html> |