commit a9a32378d0233503c1c60e01a5f2508dcc4033d6 Author: ElnuDev Date: Fri Aug 5 15:11:05 2022 -0700 Initial commit diff --git a/index.html b/index.html new file mode 100644 index 0000000..5a2f259 --- /dev/null +++ b/index.html @@ -0,0 +1,27 @@ + + + + + + nicolator + + + + + + +
+ Keymap + Keymap +
+
+ Settings ⚙️ + Seconds per kana +
+

+
+ +
+ + + diff --git a/keymap.js b/keymap.js new file mode 100644 index 0000000..654434b --- /dev/null +++ b/keymap.js @@ -0,0 +1,48 @@ +const keymap = { + "1": ["1", "?", null, "!"], + "2": ["2", "/", null, "”"], + "3": ["3", null, null, "#"], + "4": ["4", "「", null, "$"], + "5": ["5", "」", null, "%"], + "6": ["6", null, "[", "&"], + "7": ["7", null, "]", "’"], + "8": ["8", null, "(", "("], + "9": ["9", null, ")", ")"], + "0": ["0", null, null, "~"], + "-": ["-", null, null, "="], + "=": ["^", null, null, "~"], + "q": ["。", "ぁ", null, "Q"], + "w": ["か", "え", "が", "W"], + "e": ["た", "り", "だ", "E"], + "r": ["こ", "ゃ", "ご", "R"], + "t": ["さ", "れ", "ざ", "T"], + "y": ["ら", "ぱ", "よ", "Y"], + "u": ["ち", "ぢ", "に", "U"], + "i": ["く", "ぐ", "る", "I"], + "o": ["つ", "づ", "ま", "O"], + "p": [",", "ぴ", "ぇ", "P"], + "[": ["、", null, null, "‘"], + "]": ["゛", null, "゜", "{"], + "\\": ["]", null, null, "}"], + "a": ["う", "を", null, "A"], + "s": ["し", "あ", "じ", "S"], + "d": ["て", "な", "で", "D"], + "f": ["け", "ゅ", "げ", "F"], + "g": ["せ", "も", "ぜ", "G"], + "h": ["は", "ば", "み", "H"], + "j": ["と", "ど", "お", "J"], + "k": ["き", "ぎ", "の", "K"], + "l": ["い", "ぽ", "ょ", "L"], + ";": ["ん", null, "っ", "+"], + "'": [":", null, null, "*"], + "z": [".", "ぅ", null, "Z"], + "x": ["ひ", "ー", "び", "X"], + "c": ["す", "ろ", "ず", "C"], + "v": ["ふ", "や", "ぶ", "V"], + "b": ["へ", "ぃ", "べ", "B"], + "n": ["め", "ぷ", "ぬ", "N"], + "m": ["そ", "ぞ", "ゆ", "M"], + ",": ["ね", "ぺ", "む", "<"], + ".": ["ほ", "ぼ", "わ", ">"], + "/": ["・", null, "ぉ", "?"], +}; diff --git a/nicolator.js b/nicolator.js new file mode 100644 index 0000000..0f8a14e --- /dev/null +++ b/nicolator.js @@ -0,0 +1,222 @@ +// modified from https://stackoverflow.com/a/14051331 +// Issue is keycode conversion for non-alphanumeric keys (e.g. period) +// is not accurate +function convertKeyCode(evt) { + var chara = ""; + var keyCode = (evt.which) ? evt.which : evt.keyCode; + var shift = evt.shiftKey; + if (keyCode == 19) + chara = "pause/break"; + if (keyCode == 48) + chara = (shift) ? ")" : "0"; + if (keyCode == 49) + chara = (shift) ? "!" : "1"; + if (keyCode == 50) + chara = (shift) ? "@" : "2"; + if (keyCode == 51) + chara = (shift) ? "#" : "3"; + if (keyCode == 52) + chara = (shift) ? "$" : "4"; + if (keyCode == 53) + chara = (shift) ? "%" : "5"; + if (keyCode == 54) + chara = (shift) ? "^" : "6"; + if (keyCode == 55) + chara = (shift) ? "&" : "7"; + if (keyCode == 56) + chara = (shift) ? "*" : "8"; + if (keyCode == 57) + chara = (shift) ? "(" : "9"; + if (keyCode == 65) + chara = (shift) ? "A" : "a"; + if (keyCode == 66) + chara = (shift) ? "B" : "b"; + if (keyCode == 67) + chara = (shift) ? "C" : "c"; + if (keyCode == 68) + chara = (shift) ? "D" : "d"; + if (keyCode == 69) + chara = (shift) ? "E" : "e"; + if (keyCode == 70) + chara = (shift) ? "F" : "f"; + if (keyCode == 71) + chara = (shift) ? "G" : "g"; + if (keyCode == 72) + chara = (shift) ? "H" : "h"; + if (keyCode == 73) + chara = (shift) ? "I" : "i"; + if (keyCode == 74) + chara = (shift) ? "J" : "j"; + if (keyCode == 75) + chara = (shift) ? "K" : "k"; + if (keyCode == 76) + chara = (shift) ? "L" : "l"; + if (keyCode == 77) + chara = (shift) ? "M" : "m"; + if (keyCode == 78) + chara = (shift) ? "N" : "n"; + if (keyCode == 79) + chara = (shift) ? "O" : "o"; + if (keyCode == 80) + chara = (shift) ? "P" : "p"; + if (keyCode == 81) + chara = (shift) ? "Q" : "q"; + if (keyCode == 82) + chara = (shift) ? "R" : "r"; + if (keyCode == 83) + chara = (shift) ? "S" : "s"; + if (keyCode == 84) + chara = (shift) ? "T" : "t"; + if (keyCode == 85) + chara = (shift) ? "U" : "u"; + if (keyCode == 86) + chara = (shift) ? "V" : "v"; + if (keyCode == 87) + chara = (shift) ? "W" : "w"; + if (keyCode == 88) + chara = (shift) ? "X" : "x"; + if (keyCode == 89) + chara = (shift) ? "Y" : "y"; + if (keyCode == 90) + chara = (shift) ? "Z" : "z"; + if (keyCode == 93) + chara = "select key"; + if (keyCode == 186 || keyCode == 59) + chara = ";"; + if (keyCode == 187 || keyCode == 61) + chara = "="; + if (keyCode == 188) + chara = ","; + if (keyCode == 189 || keyCode == 173) + chara = "-"; + if (keyCode == 190) + chara = "."; + if (keyCode == 191) + chara = "/"; + if (keyCode == 192) + chara = "`"; + if (keyCode == 219) + chara = (shift) ? "{" : "["; + if (keyCode == 220) + chara = "\\"; + if (keyCode == 221) + chara = (shift) ? "}" : "]"; + if (keyCode == 222) + chara = "'"; + return chara; +} +const wordDisplay = document.getElementById("word"); +const input = document.getElementById("input"); +const timer = document.getElementById("timer"); +const hintDisplay = document.getElementById("hint"); + +const leftShiftCode = 32; // space +const rightShiftCode = 16; // shift key +let leftShift = false; +let rightShift = false; +let inComposition = false; +addEventListener("keydown", event => { + switch(event.keyCode) { + case leftShiftCode: + leftShift = true; + event.preventDefault(); + break; + case rightShiftCode: + rightShift = true; + event.preventDefault(); + break; + } +}); +addEventListener("keyup", event => { + switch(event.keyCode) { + case leftShiftCode: + leftShift = false; + break; + case rightShiftCode: + rightShift = false; + break; + } +}); +addEventListener("compositionstart", event => inComposition = true); +addEventListener("compositionend", event => inComposition = false); +input.addEventListener("keydown", e => { + if (inComposition) { + return; + } + const pressed = convertKeyCode(e).toLowerCase(); // String.fromCharCode(e.keyCode).toLowerCase(); + if (keymap[pressed] !== undefined) { + let valueIndex = 0; + if (leftShift && keymap[pressed][1]) { + valueIndex = 1; + } else if (rightShift && keymap[pressed][2]) { + valueIndex = 2; + } + input.value += keymap[pressed][valueIndex]; + if (input.value == word) { + clearTimeout(timeout); + wordDisplay.style.color = "green"; + wordDisplay.innerHTML += " ✅"; + setTimeout(() => { + wordDisplay.style.color = ""; + reset(); + }, 1000); + } + e.preventDefault(); + } else if (pressed == " ") { + e.preventDefault(); + } +}); +// window.requestAnimationFrame() might be better suited +// https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame +let typeTimePerKana = 2; // in seconds +const typeTimePerKanaInput = document.getElementById("timePerKana"); +typeTimePerKanaInput.value = typeTimePerKana; +typeTimePerKanaInput.addEventListener("change", (e) => { + typeTimePerKana = typeTimePerKanaInput.value; +}); +const timerFPS = 60; +let timerTimeout = null; +let timeout = null; +let word = null; +const reset = () => { + input.value = ""; + hint.innerHTML = ""; + timer.value = 1; + word = words[Math.round(Math.random() * words.length)]; + timeout = wordDisplay.innerHTML = word; + const typeTime = typeTimePerKana * word.length; + setTimeout(() => { + for (let i = 0; i < word.length; i++) { + const letter = word[i]; + let key = null; + let index = null; + for (let otherKey in keymap) { + for (let i = 0; i < keymap[otherKey].length && !key; i++) { + if (keymap[otherKey][i] == letter) { + key = otherKey; + index = i; + } + } + } + let t = `

${letter.toUpperCase()}:`; + if (index > 0) { + t += ""; + if (index == 1) { + t += "←"; + } else if (index == 2) { + t += "→"; + } else if (index == 3) { + t += "↑"; + } + t += " + "; + } + t += `${key}

`; + hint.innerHTML += t; + } + }, typeTime * 1000); + clearInterval(timerTimeout); + timerTimeout = setInterval(() => { + timer.value -= (1 / timerFPS) / typeTime; + }, 1000 / timerFPS); +}; +reset(); diff --git a/words.js b/words.js new file mode 100644 index 0000000..0dbabb8 --- /dev/null +++ b/words.js @@ -0,0 +1 @@ +const words = ["あげる", "あさ", "ふうとう", "ふゆ", "ご", "いいえ", "いっしょ", "かわいい", "きっさてん", "おかし", "おもしろい", "おねえさん", "ろうか", "しる", "たいへん", "となり", "としょかん", "ふぉおく", "せえたあ", "すぷうん", "だんだん", "ぎゅうにく", "はがき", "ひ", "ほん", "いま", "ほう", "きる", "まいあさ", "まど", "まつ", "なか", "なまえ", "にちようび", "のむ", "れんしゅう", "さむい", "した", "たいせつ", "いちにち", "つよい", "うわぎ", "わたる", "やま", "くらす", "ぜろ", "ひらく", "あそこ", "あたたかい", "びょういん", "ちがう", "ちょうど", "だれ", "げんき", "げつようび", "はる", "いる", "じどうしゃ", "かるい", "きた", "くだもの", "まるい", "みなみ", "みせ", "にもつ", "おなか", "せんしゅう", "そば", "すこし", "べっど", "どあ", "あまい", "あつい", "ちょっと", "でんき", "どちら", "えいが", "ぎゅうにゅう", "ひだり", "こども", "きく", "くつ", "くつした", "もくようび", "ねる", "おかね", "おきる", "おなじ", "おとうさん", "さとう", "せんせい", "しまる", "する", "うるさい", "わるい", "でぱあと", "ぷうる", "すとおぶ", "ぼうし", "ちかく", "でんしゃ", "えんぴつ", "ふく", "はいざら", "ひこうき", "いたい", "じしょ", "ここ", "まいつき/まいげつ", "みみ", "みんあ", "おくさん", "さい", "せ", "とぶ", "とおい", "とても", "うる", "よこ", "どうぶつ", "ふたり", "はつか", "ほんとう", "ほか", "じてんしゃ", "かぞく", "きえる", "まえ", "みせる", "もんだい", "むずかしい", "なく", "おす", "おとこ", "たんじょうび", "たのむ", "うすい", "ようか", "ざっし", "こっぷ", "あと", "でかける", "どうも", "えき", "がっこう", "がくせい", "ごぜん", "はし", "いくつ", "じゅぎょう", "つの", "かんじ", "からだ", "き", "みじかい", "のる", "おべんとう", "おもい", "およぐ", "らいしゅう", "さく", "さんぽ", "すき", "すむ", "とけい", "つとめる", "わかい", "えれべえた", "ぱあちい", "すりっぱ", "てれび", "あさごはん", "ばんごはん", "でぐち", "ふる", "ごご", "はたらく", "はやく", "ひろい", "きん’ようび", "こんしゅう", "きょうだい", "くち", "め", "ねこ", "おんあ", "おしえる", "しぬ", "ところ", "つぎ", "ゆうびんきょく", "あびる", "あらう", "だす", "はる", "へん", "へた", "いう", "じぶん", "かす", "ことし", "きょねん", "めがね", "もん", "に", "おとこ", "しんぶん", "しろい", "とまる", "とり", "つかう", "うた", "よる", "こおひい", "だいじょうぶ", "でんわ", "どうぞ", "え", "はじまる", "ひく", "じびき", "じかん", "かぜ", "こうちゃ", "まいばん", "みどり", "にぎやか", "にわ", "さくぶん", "さん", "すわる", "たまご", "と", "わかる", "あね", "あそぶ", "でる", "げんかん", "はじめて", "はたち", "ひく", "いぬ", "いりぐち", "ここのか", "くに", "まいとし", "みる", "ならぶ", "おにいさん", "おとな", "おととい", "せんたく", "しめる", "から", "たばこ", "たかい", "うまれる", "ゆうめい", "ぺっと", "あし", "どうして", "はじめ", "はこ", "はしる", "はやい", "へや", "ひと", "ひとつ", "ひゃく", "じょうず", "かいしゃ", "かく", "ふう", "まいにち", "まずい", "みち", "むこう", "おまわりさん", "さらいねん", "せまい", "しごと", "そうじ", "たべもの", "たいしかん", "たてもの", "てんき", "つまらない", "うたう", "よむ", "よわい", "ゆき", "ゆっくり", "きろ", "こおと", "てえぷ", "あかるい", "ちゃわん", "だいがく", "どこ", "ごはん", "いえ", "いろいろ", "いつつ", "いや", "かえす", "かいもの", "こたえる", "こうさてん", "くる", "まいしゅう", "みぎ", "ならべる", "おばあさん", "さいふ", "せびろ", "しゅくだい", "たつ", "ときどき", "つかれる", "わすれる", "やすむ", "ぐらむ", "あき", "あう", "がいこくじん", "ひがし", "ひとり", "いみ", "いつも", "つらい", "かう", "けさ", "むいか", "おばさん", "おふろ", "おく", "りょうしん", "さき", "しゃしん", "てがみ", "つめたい", "かみ", "うしろ", "やる", "ようふく", "あに", "あつい", "あつい", "ちかてつ", "だいどころ", "はいる", "はんぶん", "かさ", "けっこん", "おんがく", "おととし", "らいげつ", "りょうり", "しち、 なな", "そと", "たぶん", "たのしい", "うみ", "わたす", "やさい", "ばす", "ぽけっと", "あか/あかい", "あめ", "ふつか", "はれる", "いちばん", "いけ", "いくら", "きって", "くるま", "まち", "また", "ながい", "なに", "なる", "なつ", "おぼえる", "おおきい", "おわる", "せっけん", "しめる", "しお", "しょくどう", "たべる", "たくさん", "とおか", "ぶたにく", "ちち", "どう", "ふく", "ひ", "けいかん", "きっぷ", "きる", "ことば", "くすり", "にく", "おちゃ", "おかあさん", "つくえ", "つくる", "やすみ", "ぜんぶ", "あぱあと", "あぶない", "あおい", "ある", "べんり", "ふるい", "はやい", "いく", "いれる", "いそがしい", "いす", "けっこう", "こえ", "くろい", "みず", "のぼる", "ぬぐ", "おさら", "らいねん", "りょこう", "しつもん", "とし", "よっか", "すかあと", "あるく", "ちいさい", "だれか", "は", "はは", "はな", "ひくい", "かばん", "きいろい", "こんばん", "こうばん", "きょうしつ", "くらい", "まがる", "にし", "おいしい", "れいぞうこ", "せいと", "ともだち", "とる", "とる", "ぎたあ", "かめら", "ずぼん", "ばんごう", "ちゃいろ", "はち", "はな", "かえる", "きたない", "きゅう", "こんいち", "くもり", "まん", "ならう", "のみもの", "おてあらい", "さかな", "せんげつ", "すくない", "つく", "よぶ", "しゃわあ", "しゃつ", "ちかい", "ちず", "えいがかん", "ぎんこう", "はし", "ひま", "ひる", "いい", "いろ", "かぎ", "かみ", "かてい", "かわ", "けす", "きのう", "まだ", "むら", "し、 よん", "しょうゆ", "ぺん", "すぽおつ", "たくしい", "てえぷ", "あける", "あなた", "あさって", "あした", "あたま", "えいご", "はなす", "ひるごはん", "ほんだな", "いもうと", "かいだん", "きらい", "こまる", "みがく", "もつ", "なのか", "おとうと", "ろく", "りゅうがくせい", "すう", "てえぶる", "てすと", "といれ", "あたらしい", "べんきょう", "びょうき", "どようび", "がいこく", "はなし", "いち", "いちにち", "いつか", "かりる", "きれい", "なくす", "おんあ", "おおい", "おおぜい", "おりる", "おそい", "さけ", "せん", "しずか", "すいようび", "すずしい", "て", "わたし", "やすい", "ほてる"];