|
| 1 | +let content = []; |
| 2 | +// window.addEventListener('load', getData, false ) |
| 3 | +async function getData(){ |
| 4 | + let minLength = 100; |
| 5 | + content = []; |
| 6 | + try{ |
| 7 | + const resp = await fetch("https://api.quotable.io/random?minLength="+minLength); |
| 8 | + const data = await resp.json(); |
| 9 | + console.log(data); |
| 10 | + content = [data.content]; |
| 11 | + } |
| 12 | + catch(err){ |
| 13 | + console.log(err); |
| 14 | + content = [["Cosmology deals with the world as the totality of space, time and all phenomena. Historically, it has had quite a broad scope, and in many cases was founded in religion. In modern use metaphysical cosmology addresses questions about the Universe which are beyond the scope of science."]]; |
| 15 | + } |
| 16 | + finally{ |
| 17 | + console.log(content); |
| 18 | + } |
| 19 | +} |
| 20 | + |
| 21 | +getData(); |
| 22 | + |
| 23 | + |
| 24 | +let para = document.querySelector("#content-to-type"); |
| 25 | +let start = document.querySelector("#start"); |
| 26 | +let minutes = document.querySelector("#minutes"); |
| 27 | +let seconds = document.querySelector("#seconds"); |
| 28 | +let keys = document.querySelectorAll(".key"); |
| 29 | +let inputContent = document.querySelector("#input-content"); |
| 30 | +inputContent.value = ""; |
| 31 | +let errorVal = document.querySelector("#error-val"); |
| 32 | +let evaluation = document.querySelector(".evaluation"); |
| 33 | +let speedVal = document.querySelector("#speed-val"); |
| 34 | +let scoreVal = document.querySelector("#score-val"); |
| 35 | +let letters,typingLetterErrors=0; |
| 36 | + |
| 37 | + |
| 38 | +// let dataKeys = []; |
| 39 | +// for(let i = 0;i<keys.length;i++) { |
| 40 | +// dataKeys.push(keys.item(i).attributes[1].value); |
| 41 | +// } |
| 42 | + |
| 43 | +//keydown event listener |
| 44 | +document.addEventListener("keydown",keyPress); |
| 45 | + |
| 46 | +//updated input value event listener |
| 47 | +inputContent.addEventListener("input",inputChange) |
| 48 | + |
| 49 | +//start typing button event listener |
| 50 | +start.addEventListener("click", loadContent,true); |
| 51 | + |
| 52 | + |
| 53 | +//keypress animation |
| 54 | +function keyPress(event){ |
| 55 | + let keyboardCode = event.keyCode; |
| 56 | + if(keyboardCode>=48&&keyboardCode<=57) { |
| 57 | + //inputContent.removeEventListener("input",inputChange); |
| 58 | + // inputContent.innerHTML = inputContent.innerHTML.substr(0,inputContent.length-2) |
| 59 | + // console.log(keyboardCode) |
| 60 | + //inputContent.addEventListener("input",inputChange) |
| 61 | + } |
| 62 | + else { |
| 63 | + keyboardCode+=32; |
| 64 | + |
| 65 | + for(let i = 0;i<keys.length;i++) { |
| 66 | + if(parseInt(keys.item(i).attributes[1].value)===keyboardCode){ |
| 67 | + //console.log(keys.item(i).attributes[1].value) |
| 68 | + keys.item(i).classList.add("pressed"); |
| 69 | + setTimeout(()=>{ |
| 70 | + keys.item(i).classList.remove("pressed"); |
| 71 | + },100) |
| 72 | + break; |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | +} |
| 77 | + |
| 78 | +function inputChange(event){ |
| 79 | + |
| 80 | + let inputVal = inputContent.value; |
| 81 | + //.classList.remove("current"); |
| 82 | + |
| 83 | + //finding the integer equivalent of the last input character |
| 84 | + let intVal = parseInt(inputContent.value.charAt(inputContent.value.length-1)); |
| 85 | + |
| 86 | + //if integer value is not NaN i.e. it is a number, remove it from the input value |
| 87 | + if(!Number.isNaN(intVal)) inputContent.value = inputVal.substr(0,inputContent.value.length-1); |
| 88 | + // console.log(inputContent.value) |
| 89 | + let keyCode = inputVal.charCodeAt(inputVal.length-1); |
| 90 | + if(inputVal.length<=para.length-1) |
| 91 | + startBlinking(inputVal.length) |
| 92 | + checkInput(keyCode,inputVal); |
| 93 | +} |
| 94 | +function startBlinking(letterId){ |
| 95 | + |
| 96 | + window.blinkingId = setInterval(()=>{ |
| 97 | + blinking(letters.item(letterId)); |
| 98 | + },150); |
| 99 | +} |
| 100 | +function clearBlinking(){ |
| 101 | + clearInterval(window.blinkingId); |
| 102 | +} |
| 103 | +function blinking(letter){ |
| 104 | + if(letter!=null && letter.classList[1]==="current") |
| 105 | + letter.classList.remove("current"); |
| 106 | + else { |
| 107 | + letter.classList.add("current"); |
| 108 | + } |
| 109 | +} |
| 110 | + |
| 111 | +//letters.item(inputValue.length-1).innerHTML.charAt(0)==="_"&& inputValue || |
| 112 | + |
| 113 | +function checkInput(keyCode,inputValue){ |
| 114 | + if(inputValue.length===letters.length){ |
| 115 | + pauseClock("Pause"); |
| 116 | + let [minsCompleted,secsCompleted] = getCurrentTimerValue(minutes.innerHTML,seconds.innerHTML); |
| 117 | + let totalCorrect = letters.length - typingLetterErrors; |
| 118 | + let percentageCorrect = Math.floor(totalCorrect/letters.length * 100); |
| 119 | + let charsPerSecond = Math.floor(totalCorrect/(minsCompleted*60 + secsCompleted)); |
| 120 | + let wordsPerMinute = Math.floor(charsPerSecond*60)/10; |
| 121 | + speedVal.innerHTML = wordsPerMinute+" words/min"; |
| 122 | + scoreVal.innerHTML = percentageCorrect; |
| 123 | + start.innerHTML = "Restart"; |
| 124 | + //start.removeEventListener("click",loadContent,true) |
| 125 | + console.log("Percentage =" +percentageCorrect) |
| 126 | + console.log("Speed "+charsPerMinute+ " per minute") |
| 127 | + } |
| 128 | + else if(inputValue.length<letters.length){ |
| 129 | + if(keyCode>=97 && keyCode<=122 || keyCode===32){ |
| 130 | + if(keyCode===32) keyCode = 95; |
| 131 | + if(letters.item(inputValue.length-1).innerHTML.charCodeAt(0)===keyCode){ |
| 132 | + //console.log(letters.item(inputValue.length-1),inputValue) |
| 133 | + clearBlinking(); |
| 134 | + startBlinking(inputValue.length); |
| 135 | + |
| 136 | + letters.item(inputValue.length-1).classList.add("typed"); |
| 137 | + } |
| 138 | + else { |
| 139 | + typingLetterErrors++; |
| 140 | + errorVal.innerHTML = typingLetterErrors; |
| 141 | + clearBlinking(); |
| 142 | + startBlinking(inputValue.length); |
| 143 | + letters.item(inputValue.length-1).classList.add("wrong"); |
| 144 | + console.log("Errors = "+typingLetterErrors) |
| 145 | + } |
| 146 | + } |
| 147 | +} |
| 148 | +} |
| 149 | + |
| 150 | + |
| 151 | + //event.key.charCodeAt(0); |
| 152 | + |
| 153 | + //console.log(inputVal.charCodeAt(inputVal.length-1)) |
| 154 | + //checkCurrentInput(event.key,para.innerHTML.charAt(0) |
| 155 | + |
| 156 | + |
| 157 | +function loadContent(){ |
| 158 | + if(start.innerHTML==="Restart"){ |
| 159 | + window.location.reload(); |
| 160 | + } |
| 161 | + inputContent.focus(); |
| 162 | + if(start.innerHTML==="Start"){ |
| 163 | + setNewContent(); |
| 164 | + para = document.querySelector("#content-to-type"); |
| 165 | + } |
| 166 | + else if (start.innerHTML==="Resume"){ |
| 167 | + startClock(seconds.innerHTML,minutes.innerHTML,start.innerHTML);//resume timer |
| 168 | + start.innerHTML = "Pause"; |
| 169 | + } |
| 170 | + else if (start.innerHTML === "Pause"){ |
| 171 | + pauseClock(start.innerHTML); //pausing the clock |
| 172 | + start.innerHTML="Resume"; |
| 173 | + } |
| 174 | +} |
| 175 | + |
| 176 | +function setNewContent(){ |
| 177 | + typingLetterErrors=0; |
| 178 | + let paraNumber = randomParaGenerator(1); |
| 179 | + let wordsArray = wordSeparator(content[0].toLocaleLowerCase()); |
| 180 | + let typingPara =" "; |
| 181 | + wordsArray = wordsArray.filter((word)=> word.length>=1) |
| 182 | + //limiting to 25 words |
| 183 | + let letterId = 0; |
| 184 | + for(let wordIndex = 0;wordIndex<Math.min(25,wordsArray.length);wordIndex++){ |
| 185 | + let word = wordsArray[wordIndex]; |
| 186 | + console.log("word ",wordIndex,word) |
| 187 | + typingPara = typingPara+letterSeparator(word,letterId); |
| 188 | + letterId = letterId+word.length+1; |
| 189 | + } |
| 190 | + |
| 191 | + para.innerHTML = typingPara.trim(); |
| 192 | + letters = document.querySelectorAll(".typing"); |
| 193 | + startClock(seconds.innerHTML,minutes.innerHTML,start.innerHTML);//start timer |
| 194 | + start.innerHTML = "Pause"; |
| 195 | +} |
| 196 | + |
| 197 | + |
| 198 | +function wordSeparator(currContent){ |
| 199 | + return currContent.split(/[,. -_]/) |
| 200 | +} |
| 201 | + |
| 202 | + |
| 203 | +function letterSeparator(currContent,id){ |
| 204 | + let wordSpan=""; |
| 205 | + for(let charIndex=0;charIndex<currContent.length;charIndex++){ |
| 206 | + wordSpan= wordSpan + `<div class="typing" id="${id}">${currContent.charAt(charIndex)}</div>`; |
| 207 | + id++; |
| 208 | + } |
| 209 | + wordSpan.trim(); |
| 210 | + wordSpan= wordSpan + `<div class="typing" id="${id}">_</div>` |
| 211 | + return wordSpan; |
| 212 | +} |
| 213 | +function randomParaGenerator(limit){ |
| 214 | + return Math.floor(Math.random()*limit); |
| 215 | +} |
| 216 | +function startClock(secs,mins,condition){ |
| 217 | + let timerVals = getCurrentTimerValue(mins,secs); |
| 218 | + let [minsVal,secsVal] = [...timerVals]; |
| 219 | + |
| 220 | + //After every second, check the value of condition |
| 221 | + //If it is start, call the increase seconds function |
| 222 | + //IF not, do nothing |
| 223 | + |
| 224 | + startBlinking(inputContent.value.length) |
| 225 | + //using window object because using local variables result in error in pausing the clock because of scoping |
| 226 | + window.timerClockID = setInterval(() => { |
| 227 | + if(condition==="Start"|| condition==="Resume"){ |
| 228 | + secsVal = increaseSeconds(secsVal); |
| 229 | + if(secsVal>59){ |
| 230 | + secsVal = 0; |
| 231 | + minsVal=minsVal+1; |
| 232 | + } |
| 233 | + seconds.innerHTML = secsVal; |
| 234 | + minutes.innerHTML = minsVal; |
| 235 | + } |
| 236 | + }, 1000); |
| 237 | +} |
| 238 | + |
| 239 | +function getCurrentTimerValue(mins,secs){ |
| 240 | + let secsVal = parseInt(secs); |
| 241 | + let minsVal = parseInt(mins); |
| 242 | + let timer = [minsVal,secsVal]; |
| 243 | + return timer; |
| 244 | +} |
| 245 | +function increaseSeconds(secondsValue){ |
| 246 | + return secondsValue+1; |
| 247 | +} |
| 248 | +function pauseClock(condition){ |
| 249 | + if(condition==="Pause"){ |
| 250 | + clearInterval(window.timerClockID) |
| 251 | + } |
| 252 | +} |
0 commit comments