Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const keyboardLayout = {
  2.   en: {
  3.     backquote: ['`', '~'],
  4.     digit1: ['1', '!'],
  5.     digit2: ['2', '@'],
  6.     digit3: ['3', '#'],
  7.     digit4: ['4', '$'],
  8.     digit5: ['5', '%'],
  9.     digit6: ['6', '^'],
  10.     digit7: ['7', '&'],
  11.     digit8: ['8', '*'],
  12.     digit9: ['9', '('],
  13.     digit0: ['0', ')'],
  14.     minus: ['-', '_'],
  15.     equal: ['=', '+'],
  16.     backspace: ['Backspace'],
  17.     tab: ['Tab'],
  18.     keyQ: ['q', 'Q'],
  19.     keyW: ['w', 'W'],
  20.     keyE: ['e', 'E'],
  21.     keyR: ['r', 'R'],
  22.     keyT: ['t', 'T'],
  23.     keyY: ['y', 'Y'],
  24.     keyU: ['u', 'U'],
  25.     keyI: ['i', 'I'],
  26.     keyO: ['o', 'O'],
  27.     keyP: ['p', 'P'],
  28.     bracketLeft: ['[', '{'],
  29.     bracketRight: [']', '}'],
  30.     backslash: ['\\', '|'],
  31.     delete: ['DEL'],
  32.     capsLock: ['CapsLock'],
  33.     keyA: ['a', 'A'],
  34.     keyS: ['s', 'S'],
  35.     keyD: ['d', 'D'],
  36.     keyF: ['f', 'F'],
  37.     keyG: ['g', 'G'],
  38.     keyH: ['h', 'H'],
  39.     keyJ: ['j', 'J'],
  40.     keyK: ['k', 'K'],
  41.     keyL: ['l', 'L'],
  42.     semicolon: [';', ':'],
  43.     quote: ['\'', '"'],
  44.     enter: ['ENTER'],
  45.     shiftLeft: ['Shift'],
  46.     keyZ: ['z', 'Z'],
  47.     keyX: ['x', 'X'],
  48.     keyC: ['c', 'C'],
  49.     keyV: ['v', 'V'],
  50.     keyB: ['b', 'B'],
  51.     keyN: ['n', 'N'],
  52.     keyM: ['m', 'M'],
  53.     comma: [',', '<'],
  54.     period: ['.', '>'],
  55.     slash: ['/', '?'],
  56.     arrowUp: ['↑'],
  57.     shiftRight: ['Shift'],
  58.     controlLeft: ['Ctrl'],
  59.     altLeft: ['Alt'],
  60.     space: [' ', ' '],
  61.     altRight: ['Alt'],
  62.     arrowLeft: ['←'],
  63.     arrowDown: ['↓'],
  64.     arrowRight: ['→'],
  65.     controlRight: ['Ctrl'],
  66.   },
  67.   ru: {
  68.     backquote: ['ё', 'Ё'],
  69.     digit1: ['1', '!'],
  70.     digit2: ['2', '"'],
  71.     digit3: ['3', '№'],
  72.     digit4: ['4', ';'],
  73.     digit5: ['5', '%'],
  74.     digit6: ['6', ':'],
  75.     digit7: ['7', '?'],
  76.     digit8: ['8', '*'],
  77.     digit9: ['9', '('],
  78.     digit0: ['0', ')'],
  79.     dash: ['-', '_'],
  80.     equal: ['=', '+'],
  81.     backspace: ['Backspace'],
  82.     tab: ['Tab'],
  83.     keyQ: ['й', 'Й'],
  84.     keyW: ['ц', 'Ц'],
  85.     keyE: ['у', 'У'],
  86.     keyR: ['к', 'К'],
  87.     keyT: ['е', 'Е'],
  88.     keyY: ['н', 'Н'],
  89.     keyU: ['г', 'Г'],
  90.     keyI: ['ш', 'Ш'],
  91.     keyO: ['щ', 'Щ'],
  92.     keyP: ['з', 'З'],
  93.     leftBracket: ['х', 'Х'],
  94.     rightBracket: ['ъ', 'Ъ'],
  95.     backslash: ['\\', '/'],
  96.     del: ['DEL'],
  97.     capslock: ['CapsLock'],
  98.     keyA: ['ф', 'Ф'],
  99.     keyS: ['ы', 'Ы'],
  100.     keyD: ['в', 'В'],
  101.     keyF: ['а', 'А'],
  102.     keyG: ['п', 'П'],
  103.     keyH: ['р', 'Р'],
  104.     keyJ: ['о', 'О'],
  105.     keyK: ['л', 'Л'],
  106.     keyL: ['д', 'Д'],
  107.     semicolon: ['ж', 'Ж'],
  108.     quote: ['э', 'Э'],
  109.     enter: ['ENTER'],
  110.     shiftLeft: ['Shift'],
  111.     keyZ: ['я', 'Я'],
  112.     keyX: ['ч', 'Ч'],
  113.     keyC: ['с', 'С'],
  114.     keyV: ['м', 'М'],
  115.     keyB: ['и', 'И'],
  116.     keyN: ['т', 'Т'],
  117.     keyM: ['ь', 'Ь'],
  118.     comma: ['б', 'Б'],
  119.     dot: ['ю', 'Ю'],
  120.     slash: ['.', ','],
  121.     arrowUp: ['↑'],
  122.     shiftRight: ['Shift'],
  123.     controlLeft: ['Ctrl'],
  124.     altLeft: ['Alt'],
  125.     space: [' ', ' '],
  126.     altRight: ['Alt'],
  127.     arrowLeft: ['←'],
  128.     arrowDown: ['↓'],
  129.     arrowRight: ['→'],
  130.     controlRight: ['Ctrl'],
  131.   },
  132. };
  133.  
  134. const css = {
  135.   wrapper: 'wrapper',
  136.   textarea: 'textarea',
  137.   keyboard: 'keyboard',
  138.   row: 'row',
  139.   key: 'key',
  140.   backspace: 'backspace',
  141.   tab: 'tab',
  142.   delete: 'delete',
  143.   capsLock: 'capsLock',
  144.   enter: 'enter',
  145.   shift: 'shift',
  146.   ctrl: 'ctrl',
  147.   alt: 'alt',
  148.   space: 'space',
  149.   keydown: 'keydown',
  150.   switchLang: 'switchLang',
  151.   text: 'text',
  152.   hidden: 'hidden',
  153. };
  154.  
  155. const textarea = document.createElement('textarea');
  156.  
  157. function createKey() {
  158.   const key = document.createElement('div');
  159.   key.classList.add(css.key);
  160.   return key;
  161. }
  162.  
  163. const languages = ['en', 'ru'];
  164. let curLangIndex = 0;
  165.  
  166. function getLanguage() {
  167.   const langIndex = window.localStorage.getItem('language');
  168.   return (langIndex || 0);
  169. }
  170.  
  171. function saveLanguage() {
  172.   window.localStorage.setItem('language', curLangIndex);
  173. }
  174.  
  175. function getKeysByLang() {
  176.   const lang = languages[curLangIndex];
  177.   const langArr = Object.entries(keyboardLayout[lang]);
  178.   const value = langArr.map((arr) => {
  179.     const [keyID, values] = arr; /* [backquote, ['`', '~'//]] */
  180.     const [val1, val2] = values; /* ['`', '~'] */
  181.     const valVisible = document.createElement('span');
  182.  
  183.     valVisible.setAttribute('class', 'val');
  184.     valVisible.textContent = val1;
  185.  
  186.     const valHidden = document.createElement('span');
  187.     valHidden.textContent = val2;
  188.     valHidden.setAttribute('class', 'hidden');
  189.  
  190.     const key = createKey();
  191.     key.append(valVisible, valHidden);
  192.     key.id = keyID;
  193.  
  194.     key.classList.add(css.backspace);
  195.     key.classList.add(css.tab);
  196.     key.classList.add(css.delete);
  197.     key.classList.add(css.capsLock);
  198.     key.classList.add(css.enter);
  199.     key.classList.add(css.shift);
  200.     key.classList.add(css.ctrl);
  201.     key.classList.add(css.alt);
  202.     key.classList.add(css.space);
  203.  
  204.     function specialKeys(keyWord, cssClass) {
  205.       if (val1 !== keyWord) {
  206.         key.classList.remove(cssClass);
  207.       }
  208.       return key;
  209.     }
  210.  
  211.     specialKeys('Backspace', 'backspace');
  212.     specialKeys('Tab', 'tab');
  213.     specialKeys('DEL', 'delete');
  214.     specialKeys('CapsLock', 'capsLock');
  215.     specialKeys('ENTER', 'enter');
  216.     specialKeys('Shift', 'shift');
  217.     specialKeys('Ctrl', 'ctrl');
  218.     specialKeys('Alt', 'alt');
  219.     specialKeys(' ', 'space');
  220.  
  221.     return key;
  222.   });
  223.  
  224.   return value;
  225. }
  226.  
  227. function createRowsWithKeys(keysAmount, allKeys, startIndex) {
  228.   const row = document.createElement('div');
  229.   row.classList.add(css.row);
  230.  
  231.   for (let i = startIndex; i < startIndex + keysAmount; i += 1) {
  232.     row.append(allKeys[i]);
  233.   }
  234.   return row;
  235. }
  236.  
  237. function createRows(allKeys) {
  238.   const row1 = createRowsWithKeys(14, allKeys, 0);
  239.   const row2 = createRowsWithKeys(15, allKeys, 14);
  240.   const row3 = createRowsWithKeys(13, allKeys, 29);
  241.   const row4 = createRowsWithKeys(13, allKeys, 42);
  242.   const row5 = createRowsWithKeys(8, allKeys, 55);
  243.   return [row1, row2, row3, row4, row5];
  244. }
  245.  
  246. function changeLayout() {
  247.   curLangIndex = (curLangIndex + 1) % languages.length;
  248.   saveLanguage();
  249.   const lang = languages[curLangIndex];
  250.   const keys = getKeysByLang(lang);
  251.   const keyboard = document.querySelector('.keyboard');
  252.   keyboard.innerHTML = '';
  253.   keyboard.append(...createRows(keys));
  254. }
  255.  
  256. let isShiftDown = false;
  257. let isCtrlDown = false;
  258.  
  259. const shift = () => {
  260.   const visible = document.querySelector('.val');
  261.   const hidden = document.querySelector('.hidden');
  262.   visible.forEach((v) => {
  263.     v.classList.add('hidden');
  264.   });
  265.   hidden.forEach((h) => {
  266.     h.classList.remove('hidden');
  267.     h.classList.add('val');
  268.   });
  269. };
  270.  
  271. const printSpecialKey = (key) => {
  272.   switch (key) {
  273.     case 'Tab':
  274.       textarea.value += '  ';
  275.       break;
  276.     case 'ENTER':
  277.       textarea.value += '\n';
  278.       break;
  279.     case 'Alt':
  280.     case 'Ctrl':
  281.     case 'DEL':
  282.     case '↑':
  283.     case '↓':
  284.       textarea.value += '';
  285.       break; /*
  286.     case 'Shift':
  287.       shift();
  288.       break; */
  289.     case 'Backspace':
  290.       textarea.value = textarea.value.slice(0, -1);
  291.       break;
  292.     case '←':
  293.       textarea.selectionStart -= 1;
  294.       textarea.selectionEnd = textarea.selectionStart;
  295.       break;
  296.     case '→':
  297.       textarea.selectionStart += 1;
  298.       textarea.selectionEnd = textarea.selectionStart;
  299.       break;
  300.     default:
  301.       textarea.value += key;
  302.       break;
  303.   }
  304.   textarea.innerHTML += key;
  305. };
  306.  
  307. function handleKeydown(event) {
  308.   event.preventDefault();
  309.   const keyID = `#${event.code[0].toLowerCase()}${event.code.substring(1)}`; /* make 1st letter in event.code capitalized */
  310.   const keyElem = document.querySelector(keyID);
  311.   keyElem.classList.add(css.keydown);
  312.  
  313.   printSpecialKey(keyElem.textContent);
  314.  
  315.   if (event.code === 'ShiftLeft' || event.code === 'ShiftRight') {
  316.     isShiftDown = true;
  317.     shift();
  318.   }
  319.  
  320.   if (event.shiftKey === true) isShiftDown = true;
  321.   else isShiftDown = false;
  322.  
  323.   if (event.ctrlKey === true) isCtrlDown = true;
  324.   else isCtrlDown = false;
  325.  
  326.   if (isShiftDown && isCtrlDown) changeLayout();
  327.  
  328.   return true;
  329. }
  330.  
  331. function handleKeyup(event) {
  332.   event.preventDefault();
  333.   const keyID = `#${event.code[0].toLowerCase()}${event.code.substring(1)}`;
  334.   const keyElem = document.querySelector(keyID);
  335.   keyElem.classList.remove(css.keydown);
  336.   if (event.code === 'ShiftLeft' || event.code === 'ShiftRight') {
  337.     isShiftDown = false;
  338.     shift();
  339.   }
  340.  
  341.   return true;
  342. }
  343.  
  344. function createElements() {
  345.   const wrapper = document.createElement('div');
  346.   wrapper.classList.add(css.wrapper);
  347.  
  348.   textarea.style = 'resize: none;';
  349.   textarea.setAttribute('cols', 80);
  350.   textarea.setAttribute('rows', 10);
  351.   document.body.appendChild(textarea);
  352.   textarea.classList.add(css.textarea);
  353.  
  354.   const keyboard = document.createElement('div');
  355.   keyboard.classList.add(css.keyboard);
  356.   wrapper.append(textarea, keyboard);
  357.  
  358.   const allKeys = getKeysByLang();
  359.   curLangIndex = getLanguage();
  360.   saveLanguage();
  361.  
  362.   const rows = createRows(allKeys);
  363.   keyboard.append(...rows);
  364.  
  365.   const howToSwitchLang = document.createElement('div');
  366.   howToSwitchLang.classList.add(css.switchLang);
  367.   howToSwitchLang.innerHTML = '<p><strong>Shift + Ctrl</strong> - to switch language (переключить язык)</p>';
  368.   wrapper.appendChild(howToSwitchLang);
  369.  
  370.   return wrapper;
  371. }
  372.  
  373. function mouseDownHandler(elem) {
  374.   elem.classList.add(css.keydown);
  375.   printSpecialKey(elem.textContent);
  376. }
  377.  
  378. function mouseUpHandler(elem) {
  379.   elem.classList.remove(css.keydown);
  380. }
  381.  
  382. window.addEventListener('load', () => {
  383.   const pageElements = createElements();
  384.   document.querySelector('body').appendChild(pageElements);
  385.   window.addEventListener('keydown', handleKeydown);
  386.   window.addEventListener('keyup', handleKeyup);
  387.  
  388.   document.querySelectorAll('.key').forEach((element) => {
  389.     element.addEventListener('mousedown', () => mouseDownHandler(element));
  390.     element.addEventListener('mouseup', () => mouseUpHandler(element));
  391.   });
  392. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement