diff --git a/src/js/commandline.js b/src/js/commandline.js index c460784be..cff7c05ca 100644 --- a/src/js/commandline.js +++ b/src/js/commandline.js @@ -696,7 +696,7 @@ let commands = { display: "Toggle Monkey", visible: false, exec: () => { - $("#monkey").toggleClass("hidden"); + toggleMonkey(); }, }, ], diff --git a/src/js/misc.js b/src/js/misc.js index ba9ecce52..b3250d430 100644 --- a/src/js/misc.js +++ b/src/js/misc.js @@ -575,3 +575,22 @@ export function isUsernameValid(name) { if (/^\..*/.test(name.toLowerCase())) return false; return /^[0-9a-zA-Z_.-]+$/.test(name); } + +export function mapRange(x, in_min, in_max, out_min, out_max) { + let num = ((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min; + + if (out_min > out_max) { + if (num > out_min) { + num = out_min; + } else if (num < out_max) { + num = out_max; + } + } else { + if (num < out_min) { + num = out_min; + } else if (num > out_max) { + num = out_max; + } + } + return num; +} diff --git a/src/js/monkey.js b/src/js/monkey.js index a49182dd7..a6c5f8266 100644 --- a/src/js/monkey.js +++ b/src/js/monkey.js @@ -1,3 +1,5 @@ +import { mapRange } from "./misc"; + let left = false; let right = false; let elements = { @@ -6,6 +8,12 @@ let elements = { "01": document.querySelector("#monkey .right"), 11: document.querySelector("#monkey .both"), }; +let elementsFast = { + "00": document.querySelector("#monkey .fast .up"), + 10: document.querySelector("#monkey .fast .left"), + "01": document.querySelector("#monkey .fast .right"), + 11: document.querySelector("#monkey .fast .both"), +}; let last = "right"; // 0 up // 1 down @@ -15,14 +23,27 @@ function update() { Object.keys(elements).forEach((key) => { elements[key].classList.add("hidden"); }); + Object.keys(elementsFast).forEach((key) => { + elementsFast[key].classList.add("hidden"); + }); let id = left ? "1" : "0"; id += right ? "1" : "0"; elements[id].classList.remove("hidden"); + elementsFast[id].classList.remove("hidden"); } } +export function updateFastOpacity(num) { + let opacity = mapRange(num, 100, 200, 0, 1); + $("#monkey .fast").animate({ opacity: opacity }, 1000); + let animDuration = mapRange(num, 100, 200, 0.5, 0.01); + if (animDuration == 0.5) animDuration = 0; + console.log(num + " > " + animDuration); + $("#monkey").css({ animationDuration: animDuration + "s" }); +} + export function type() { if (!left && last == "right") { left = true; @@ -42,4 +63,3 @@ export function stop() { } update(); } - diff --git a/src/js/script.js b/src/js/script.js index 3c53f4752..0c8dedd21 100644 --- a/src/js/script.js +++ b/src/js/script.js @@ -2828,6 +2828,7 @@ function startTest() { updateLiveWpm(wpmAndRaw.wpm, wpmAndRaw.raw); wpmHistory.push(wpmAndRaw.wpm); rawHistory.push(wpmAndRaw.raw); + Monkey.updateFastOpacity(wpmAndRaw.wpm); let acc = Misc.roundTo2( (accuracyStats.correct / @@ -3024,6 +3025,8 @@ function restartTest(withSameWordset = false, nosave = false) { }, 125, async () => { + $("#monkey .fast").stop(true, true).css("opacity", 0); + $("#monkey").stop(true, true).css({ animationDuration: "0s" }); $("#typingTest").css("opacity", 0).removeClass("hidden"); if (!withSameWordset) { sameWordset = false; diff --git a/src/js/userconfig.js b/src/js/userconfig.js index 24aac74fc..72c2a75fe 100644 --- a/src/js/userconfig.js +++ b/src/js/userconfig.js @@ -74,6 +74,7 @@ let defaultConfig = { minAcc: "off", minAccCustom: 90, showLiveAcc: false, + monkey: false, }; let cookieConfig = null; @@ -1272,6 +1273,29 @@ function setLanguage(language, nosave) { if (!nosave) saveConfigToCookie(); } +function toggleMonkey(nosave) { + config.monkey = !config.monkey; + if (config.monkey) { + $("#monkey").removeClass("hidden"); + } else { + $("#monkey").addClass("hidden"); + } + if (!nosave) saveConfigToCookie(); +} + +function setMonkey(monkey, nosave) { + if (monkey === null || monkey === undefined) { + monkey = false; + } + config.monkey = monkey; + if (config.monkey) { + $("#monkey").removeClass("hidden"); + } else { + $("#monkey").addClass("hidden"); + } + if (!nosave) saveConfigToCookie(); +} + function setCapsLockBackspace(capsLockBackspace, nosave) { if (capsLockBackspace === null || capsLockBackspace === undefined) { capsLockBackspace = false; @@ -1550,6 +1574,7 @@ function applyConfig(configObj) { setStartGraphsAtZero(configObj.startGraphsAtZero, true); setStrictSpace(configObj.strictSpace, true); setMode(configObj.mode, true); + setMonkey(configObj.monkey, true); try { setEnableAds(configObj.enableAds, true); diff --git a/src/sass/style.scss b/src/sass/style.scss index 5745dd5ef..23fcd33e7 100644 --- a/src/sass/style.scss +++ b/src/sass/style.scss @@ -3386,6 +3386,9 @@ key { width: 308px; height: 0; margin: 0 auto; + animation: shake; + animation-duration: 0s; + animation-iteration-count: infinite; div { height: 200px; width: 308px; @@ -3403,6 +3406,32 @@ key { .both { background-image: url("../m4.png"); } + .fast { + .up { + background-image: url("../m3_fast.png"); + } + .left { + background-image: url("../m1_fast.png"); + } + .right { + background-image: url("../m2_fast.png"); + } + .both { + background-image: url("../m4_fast.png"); + } + } +} + +@keyframes shake { + 0% { + transform: translate(4px, 0) rotate(0deg); + } + 50% { + transform: translate(-4px, 0) rotate(0deg); + } + 100% { + transform: translate(4px, 0) rotate(0deg); + } } .keymap { diff --git a/static/index.html b/static/index.html index 91e7a4973..d4caa8dc6 100644 --- a/static/index.html +++ b/static/index.html @@ -1229,6 +1229,12 @@
+