jiangwei小站
1610 字
8 分钟
全键盘
2024-06-18

父组件

<keyboard
  @onKeyPress="onKeyPress"
  @onKeyReleased="onKeyReleased"
></keyboard>

<script setup lang="ts">
function onKeyPress(button: string) {
  const keyboardEvent = new KeyboardEvent("keydown", {
    code: keyboardObj[button],
  });
  window.dispatchEvent(keyboardEvent);
}
function onKeyReleased(button: string) {
  const keyboardEvent2 = new KeyboardEvent("keyup", {
    code: keyboardObj[button],
  });
  window.dispatchEvent(keyboardEvent2);
}
</script>

子组件

npm install --save simple-keyboard
<template>
  <!-- :style="{ width: `${width}px` }" -->
  <div
    @touchstart="touchStart"
    @mousedown="mousedown"
    class="keyboardContainer w-full"
  >
    <div @touchend="close" class="down">
      <img src="@/assets/images/game/icon-down.png" alt="icon" />
    </div>
    <div class="simple-keyboard-main"></div>

    <div class="controlArrows">
      <div class="simple-keyboard-control"></div>
      <div class="simple-keyboard-arrows"></div>
    </div>

    <div class="numPad">
      <div class="simple-keyboard-numpad"></div>
      <div class="simple-keyboard-numpadEnd"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import Keyboard from "simple-keyboard";
import "simple-keyboard/build/css/index.css";
import { onUnmounted } from "vue";
import { onMounted } from "vue";

defineProps(["width"]);
const emit = defineEmits(["close", "onKeyPress", "onKeyReleased"]);

let keyboard: any = null;
let keyboardControlPad: any = null;
let keyboardArrows: any = null;
let keyboardNumPad: any = null;
let keyboardNumPadEnd: any = null;

onMounted(() => {
  console.log("keyboard mounted");

  let commonKeyboardOptions = {
    onChange: (input: string) => onChange(input),
    onKeyPress: (button: string) => onKeyPress(button),
    onKeyReleased: (button: string) => onKeyReleased(button),
    theme: "simple-keyboard hg-theme-default hg-layout-default",
    physicalKeyboardHighlight: false,
    syncInstanceInputs: true,
    mergeDisplay: true,
    debug: false,
  };
  keyboard = new Keyboard(".simple-keyboard-main", {
    ...commonKeyboardOptions,
    layout: {
      default: [
        "{escape} {F1} {F2} {F3} {F4} {F5} {F6} {F7} {F8} {F9} {F10} {F11} {F12}",
        "` 1 2 3 4 5 6 7 8 9 0 - = {backspace}",
        "{tab} q w e r t y u i o p [ ] \\",
        "{capslock} a s d f g h j k l ; ' {enter}",
        "{shiftleft} z x c v b n m , . / {shiftright}",
        "{controlleft} {windowsleft} {altleft} {space} {altright} {windowsright} {fn} {controlright}",
      ],
      shift: [
        "{escape} {F1} {F2} {F3} {F4} {F5} {F6} {F7} {F8} {F9} {F10} {F11} {F12}",
        "~ ! @ # $ % ^ & * ( ) _ + {backspace}",
        "{tab} Q W E R T Y U I O P { } |",
        '{capslock} A S D F G H J K L : " {enter}',
        "{shiftleft} Z X C V B N M < > ? {shiftright}",
        "{controlleft} {windowsleft} {altleft} {space} {altright} {windowsright} {fn} {controlright}",
      ],
      capslock: [
        "{escape} {F1} {F2} {F3} {F4} {F5} {F6} {F7} {F8} {F9} {F10} {F11} {F12}",
        "~ ! @ # $ % ^ & * ( ) _ + {backspace}",
        "{tab} Q W E R T Y U I O P { } |",
        '{capslock} A S D F G H J K L : " {enter}',
        "{shiftleft} Z X C V B N M < > ? {shiftright}",
        "{controlleft} {windowsleft} {altleft} {space} {altright} {windowsright} {fn} {controlright}",
      ],
    },
    display: {
      "{escape}": "Esc",
      "{tab}": "Tab",
      "{backspace}": "Backspace",
      "{enter}": "Enter ↵",
      "{capslock}": "Caps lock",
      "{shiftleft}": "Shift ⇧",
      "{shiftright}": "Shift ⇧",
      "{controlleft}": "Ctrl",
      "{controlright}": "Ctrl",
      "{altleft}": "Alt",
      "{altright}": "Alt",
      "{windowsleft}": "Win",
      "{windowsright}": "Win",
      "{fn}": "Fn",
      "{F1}": "F1",
      "{F2}": "F2",
      "{F3}": "F3",
      "{F4}": "F4",
      "{F5}": "F5",
      "{F6}": "F6",
      "{F7}": "F7",
      "{F8}": "F8",
      "{F9}": "F9",
      "{F10}": "F10",
      "{F11}": "F11",
      "{F12}": "F12",
    },
  });
  keyboardControlPad = new Keyboard(".simple-keyboard-control", {
    ...commonKeyboardOptions,
    layout: {
      default: [
        "{prtscr} {scrolllock} {pause}",
        "{insert} {home} {pageup}",
        "{delete} {end} {pagedown}",
      ],
    },
    display: {
      "{prtscr}": "Print",
      "{scrolllock}": "Scroll",
      "{pause}": "Pause",
      "{insert}": "Ins",
      "{home}": "Home",
      "{pageup}": "PgUp",
      "{delete}": "Del",
      "{end}": "End",
      "{pagedown}": "PgDn",
    },
  });
  keyboardArrows = new Keyboard(".simple-keyboard-arrows", {
    ...commonKeyboardOptions,
    layout: {
      default: ["{arrowup}", "{arrowleft} {arrowdown} {arrowright}"],
    },
  });
  keyboardNumPad = new Keyboard(".simple-keyboard-numpad", {
    ...commonKeyboardOptions,
    layout: {
      default: [
        "{numlock} {numpaddivide} {numpadmultiply}",
        "{numpad7} {numpad8} {numpad9}",
        "{numpad4} {numpad5} {numpad6}",
        "{numpad1} {numpad2} {numpad3}",
        "{numpad0} {numpaddecimal}",
      ],
    },
    display: {
      "{numlock}": "Num",
    },
  });
  keyboardNumPadEnd = new Keyboard(".simple-keyboard-numpadEnd", {
    ...commonKeyboardOptions,
    layout: {
      default: ["{numpadsubtract}", "{numpadadd}", "{numpadenter}"],
    },
    display: {
      "{numpadenter}": "↵",
    },
  });
});

onUnmounted(() => {
  console.log("onUnmounted");
  keyboard.destroy();
  keyboardControlPad.destroy();
  keyboardArrows.destroy();
  keyboardNumPad.destroy();
  keyboardNumPadEnd.destroy();
  keyboard = null;
  keyboardControlPad = null;
  keyboardArrows = null;
  keyboardNumPad = null;
  keyboardNumPadEnd = null;
});

function touchStart(e: any) {
  e.preventDefault();
}
function mousedown(e: any) {
  e.preventDefault();
}

// function handleShift() {
//   let currentLayout = keyboard.options.layoutName;
//   let shiftToggle = currentLayout === "default" ? "shift" : "default";
//   keyboard.setOptions({
//     layoutName: shiftToggle,
//   });
// }

function handleChange(str: string) {
  keyboard.setOptions({
    layoutName: str,
  });
}

function onChange(_input: string) {
  // console.log("onChange", input);
}

let shiftToggle = "default";

function onKeyPress(button: string) {
  // console.log("onKeyPress", button);
  if (
    button === "{shift}" ||
    button === "{shiftleft}" ||
    button === "{shiftright}"
  ) {
    let a = shiftToggle === "default" ? "capslock" : "default";
    handleChange(a);
  }

  if (button === "{capslock}") {
    let currentLayout = keyboard.options.layoutName;
    shiftToggle = currentLayout === "default" ? "capslock" : "default";
    handleChange(shiftToggle);
  }
  emit("onKeyPress", button);
}

function onKeyReleased(button: string) {
  if (
    button === "{shift}" ||
    button === "{shiftleft}" ||
    button === "{shiftright}"
  ) {
    handleChange(shiftToggle);
  }
  emit("onKeyReleased", button);
}

function close() {
  emit("close");
}
</script>

<style lang="scss" scoped>
.keyboardContainer {
  position: absolute;
  left: 50%;
  bottom: 0;
  display: flex;
  background-color: rgba(0, 0, 0, 0.1);
  justify-content: center;
  margin: 0 auto;
  border-radius: 5px;
  transform: translateX(-50%);
  transform-origin: center bottom;
  background: rgba(29, 23, 46, 1);
  padding: 5px 10px;
  opacity: 0.9;
  .down {
    position: absolute;
    width: 84px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(29, 23, 46, 1);
    border-radius: 20px 20px 0px 0px;
    right: 0;
    top: -34px;
    img {
      width: 24px;
      height: 16px;
    }
  }

  :deep(.hg-button-space) {
    width: 150px;
  }

  .simple-keyboard.hg-theme-default {
    display: inline-block;
  }

  .simple-keyboard-main.simple-keyboard {
    // width: 640px;
    // min-width: 640px;
    background-color: transparent;
  }

  .simple-keyboard-main.simple-keyboard .hg-row:first-child {
    margin-bottom: 10px;
  }

  .simple-keyboard-arrows.simple-keyboard {
    align-self: flex-end;
    background-color: transparent;
  }

  .simple-keyboard .hg-button.selectedButton {
    background-color: rgba(5, 25, 70, 0.53);
    color: white;
  }

  .simple-keyboard .hg-button.emptySpace {
    pointer-events: none;
    background-color: transparent;
    border: none;
    box-shadow: none;
  }

  .simple-keyboard-arrows .hg-row {
    justify-content: center;
  }

  .simple-keyboard-arrows .hg-button {
    width: 50px;
    flex-grow: 0;
    justify-content: center;
    display: flex;
    align-items: center;
  }

  :deep(.hg-button) {
    background: rgba(89, 82, 98, 1) !important;
    box-shadow: none;
    border-bottom: 0px solid;
    color: rgba(179, 179, 179, 1) !important;
    font-size: 20px;
    padding: 10px;
  }

  :deep(.hg-activeButton) {
    background: rgba(89, 82, 98, 0.5) !important;
  }

  .controlArrows {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-flow: column;
  }

  .simple-keyboard-control.simple-keyboard {
    background-color: transparent;
  }

  .simple-keyboard-control.simple-keyboard .hg-row:first-child {
    margin-bottom: 10px;
  }

  .simple-keyboard-control .hg-button {
    width: 50px;
    flex-grow: 0;
    justify-content: center;
    display: flex;
    align-items: center;
  }

  .numPad {
    display: flex;
    align-items: flex-end;
  }

  .simple-keyboard-numpad.simple-keyboard {
    background-color: transparent;
  }

  .simple-keyboard-numpad.simple-keyboard {
    width: 160px;
  }

  .simple-keyboard-numpad.simple-keyboard .hg-button {
    width: 50px;
    justify-content: center;
    display: flex;
    align-items: center;
  }

  .simple-keyboard-numpadEnd.simple-keyboard {
    width: 50px;
    background: transparent;
    margin: 0;
    padding: 5px 5px 5px 0;
  }

  .simple-keyboard-numpadEnd.simple-keyboard .hg-button {
    align-items: center;
    justify-content: center;
    display: flex;
  }

  .simple-keyboard-numpadEnd .hg-button.hg-standardBtn.hg-button-plus {
    height: 85px;
  }

  .simple-keyboard-numpadEnd.simple-keyboard .hg-button.hg-button-enter {
    height: 85px;
  }

  .simple-keyboard.hg-theme-default .hg-button.hg-selectedButton {
    background: rgba(5, 25, 70, 0.53);
    color: white;
  }

  .hg-button.hg-functionBtn.hg-button-space {
    width: 350px;
  }
}
</style>
export const keyboardObj: any = {
  "{escape}": "Escape",
  "{F1}": "F1",
  "{F2}": "F2",
  "{F3}": "F3",
  "{F4}": "F4",
  "{F5}": "F5",
  "{F6}": "F6",
  "{F7}": "F7",
  "{F8}": "F8",
  "{F9}": "F9",
  "{F10}": "F10",
  "{F11}": "F11",
  "{F12}": "F12",
  "`": "Backquote",
  1: "Digit1",
  2: "Digit2",
  3: "Digit3",
  4: "Digit4",
  5: "Digit5",
  6: "Digit6",
  7: "Digit7",
  8: "Digit8",
  9: "Digit9",
  0: "Digit0",
  "-": "Minus",
  "=": "Equal",
  "{backspace}": "Backspace",
  "[": "BracketLeft",
  "]": "BracketRight",
  "\\": "Backslash",
  ";": "Semicolon",
  "'": "Quote",
  ",": "Comma",
  ".": "Period",
  "/": "Slash",
  "{": "BracketLeft",
  "}": "BracketRight",
  "|": "Backslash",
  "{space}": "Space",
  q: "KeyQ",
  w: "KeyW",
  e: "KeyE",
  r: "KeyR",
  t: "KeyT",
  y: "KeyY",
  u: "KeyU",
  i: "KeyI",
  o: "KeyO",
  p: "KeyP",
  a: "KeyA",
  s: "KeyS",
  d: "KeyD",
  f: "KeyF",
  g: "KeyG",
  h: "KeyH",
  j: "KeyJ",
  k: "KeyK",
  l: "KeyL",
  z: "KeyZ",
  x: "KeyX",
  c: "KeyC",
  v: "KeyV",
  b: "KeyB",
  n: "KeyN",
  m: "KeyM",
  Q: "KeyQ",
  W: "KeyW",
  E: "KeyE",
  R: "KeyR",
  T: "KeyT",
  Y: "KeyY",
  U: "KeyU",
  I: "KeyI",
  O: "KeyO",
  P: "KeyP",
  A: "KeyA",
  S: "KeyS",
  D: "KeyD",
  F: "KeyF",
  G: "KeyG",
  H: "KeyH",
  J: "KeyJ",
  K: "KeyK",
  L: "KeyL",
  Z: "KeyZ",
  X: "KeyX",
  C: "KeyC",
  V: "KeyV",
  B: "KeyB",
  N: "KeyN",
  M: "KeyM",
  "{shiftleft}": "ShiftLeft",
  "{shiftright}": "ShiftRight",
  "{controlleft}": "ControlLeft",
  "{controlright}": "ControlRight",
  "{altleft}": "AltLeft",
  "{altright}": "AltRight",
  "{windowsleft}": "OSLeft",
  "{windowsright}": "OSRight",
  "{fn}": "Fn",
  "{prtscr}": "PrintScreen",
  "{scrolllock}": "ScrollLock",
  "{pause}": "Pause",
  "{insert}": "Insert",
  "{home}": "Home",
  "{pageup}": "PageUp",
  "{delete}": "Delete",
  "{end}": "End",
  "{pagedown}": "PageDown",
  "{arrowup}": "ArrowUp",
  "{arrowleft}": "ArrowLeft",
  "{arrowdown}": "ArrowDown",
  "{arrowright}": "ArrowRight",
  "{numlock}": "NumLock",
  "{numpaddivide}": "NumpadDivide",
  "{numpadmultiply}": "NumpadMultiply",
  "{numpadsubtract}": "NumpadSubtract",
  "{numpadadd}": "NumpadAdd",
  "{numpadenter}": "NumpadEnter",
  "{numpad1}": "Numpad1",
  "{numpad2}": "Numpad2",
  "{numpad3}": "Numpad3",
  "{numpad4}": "Numpad4",
  "{numpad5}": "Numpad5",
  "{numpad6}": "Numpad6",
  "{numpad7}": "Numpad7",
  "{numpad8}": "Numpad8",
  "{numpad9}": "Numpad9",
  "{numpad0}": "Numpad0",
  "{numpaddecimal}": "NumpadDecimal",
  "{capslock}": "CapsLock",
  "{tab}": "Tab",
  "{enter}": "Enter",
};

export const keyboardMsg: any = {
  "{escape}": "Esc",
  "{F1}": "F1",
  "{F2}": "F2",
  "{F3}": "F3",
  "{F4}": "F4",
  "{F5}": "F5",
  "{F6}": "F6",
  "{F7}": "F7",
  "{F8}": "F8",
  "{F9}": "F9",
  "{F10}": "F10",
  "{F11}": "F11",
  "{F12}": "F12",
  "`": "`",
  1: "1",
  2: "2",
  3: "3",
  4: "4",
  5: "5",
  6: "6",
  7: "7",
  8: "8",
  9: "9",
  0: "0",
  "-": "-",
  "=": "=",
  "{backspace}": "Backspace",
  "[": "[",
  "]": "]",
  "\\": "Backslash",
  ";": ";",
  "'": "'",
  ",": ",",
  ".": ".",
  "/": "/",
  "{": "{",
  "}": "}",
  "|": "|",
  "{space}": "Space",
  q: "q",
  w: "w",
  e: "e",
  r: "r",
  t: "t",
  y: "y",
  u: "u",
  i: "i",
  o: "o",
  p: "p",
  a: "a",
  s: "s",
  d: "d",
  f: "f",
  g: "g",
  h: "h",
  j: "j",
  k: "k",
  l: "l",
  z: "z",
  x: "x",
  c: "c",
  v: "v",
  b: "b",
  n: "n",
  m: "m",
  Q: "Q",
  W: "W",
  E: "E",
  R: "R",
  T: "T",
  Y: "Y",
  U: "U",
  I: "I",
  O: "O",
  P: "P",
  A: "A",
  S: "S",
  D: "D",
  F: "F",
  G: "G",
  H: "H",
  J: "J",
  K: "K",
  L: "L",
  Z: "Z",
  X: "X",
  C: "C",
  V: "V",
  B: "B",
  N: "N",
  M: "M",
  "{shiftleft}": "Shift",
  "{shiftright}": "Shift",
  "{controlleft}": "Control",
  "{controlright}": "Control",
  "{altleft}": "Alt",
  "{altright}": "Alt",
  "{windowsleft}": "win",
  "{windowsright}": "win",
  "{fn}": "Fn",
  "{prtscr}": "PrintScreen",
  "{scrolllock}": "ScrollLock",
  "{pause}": "Pause",
  "{insert}": "Insert",
  "{home}": "Home",
  "{pageup}": "PageUp",
  "{delete}": "Delete",
  "{end}": "End",
  "{pagedown}": "PageDown",
  "{arrowup}": "Up",
  "{arrowleft}": "Left",
  "{arrowdown}": "Down",
  "{arrowright}": "Right",
  "{numlock}": "NumLock",
  "{numpaddivide}": "Divide",
  "{numpadmultiply}": "Multiply",
  "{numpadsubtract}": "Subtract",
  "{numpadadd}": "Add",
  "{numpadenter}": "NumpadEnter",
  "{numpad1}": "1",
  "{numpad2}": "2",
  "{numpad3}": "3",
  "{numpad4}": "4",
  "{numpad5}": "5",
  "{numpad6}": "6",
  "{numpad7}": "7",
  "{numpad8}": "8",
  "{numpad9}": "9",
  "{numpad0}": "0",
  "{numpaddecimal}": "Decimal",
  "{capslock}": "CapsLock",
  "{tab}": "Tab",
  "{enter}": "Enter",
};