Build a Simple Game to Practice Drag Clicking | Minecraft | HTML | CSS | JAVASCRIPT
Tags: html, css, javascript
Published: 2021-05-09 11:21:21

Drag clicking is one of the most commonly used techniques by the Minecraft gaming community.  Unlike the traditional clicking, this technique helps to get an immense amount of clicks which can lead you so far in the Minecraft game. In simple words, if you want to dominate in Minecraft PVP game mode, you need to be good at clicking with your mouse. This simple [Drag Clicking Test](https://joltfly.com/drag-click-test/) allows the users to test how good they are at drag clicking and enables them to get to know about their standings. 
##Rules of this Game
This game is simple and easy to use there are no complex rules, to be honest. You just have to use your mouse to perform drag clicking on this game which will eventually get you results there are few limitations in this games such as:
Users can select a time limit ranging from 1 second up to 10 seconds.
Users have to click on the dedicated area in order to get their clicks registered.
##Features of this Game
There are plenty of features that make this game stand out one of the Core features of this game is that it is quite simple and easy to use anybody can simply use it without any hassle some of the key features are listed below:
It shows the remaining time.
If it shows the real-time CPS score.
Users can opt for light and dark modes as per their comfort level. 

###A Video Guide to Drag Clicking
If you are relatively new to drag clicking or you are not that much familiar with drag clicking or simply you want to know how to perform drag clicks while aiming in a better or most efficient way you can follow [ this video link ](https://www.youtube.com/watch?v=LFM5jF5gIQI)to a YouTube video further enhance your skills to reach the god level OR simply follow [ this video ](https://www.youtube.com/watch?v=zzM7S9hMeJUI) to learn basic drag clicking on any mouse.
##Complete Source Code of this Game
Here is a complete source code of the drag click test game  don't just copy this game and use it as per your requirements but I will encourage you guys to take this project as a starter and amend it as per your needs and your vacation in order to excel in your programming skills. 
###HTML
```html
<button id="click"></button>
<div id="textDiv">
   <p id="cps">0</p>
   <p id="timeRemaining">0</p>
   <p id="clickCount"></p>
  <p id="allTime" title="Double click to reset"></p>
</div>
<div id="slider-container">
  <label id="time" for="timeSlider">2</label>
  <input type="range" min="1" max="10" id="timeSlider" value="2">
  <input type="checkbox" id="darkTheme">
  <label for="darkTheme">Dark Theme</label>
</div>
```
###CSS
```css
body {
  --bg-color: white;
  --text-color: black;
  --click-color: rgb(235,235,235);
  --shadow-color: rgb(190,190,190);
  
  background-color: var(--bg-color);
  color: var(--text-color);
  overflow: hidden;
}


#click {
  background-color: var(--click-color);
  width: 80vh;
  height:80vh;
  border-radius:50%;
  box-shadow:0 0 20px var(--shadow-color);
  position:relative;
  border: none;
  font-size:1em;
}
#click.play-again::after {
  content: "Click me to play again!";
}
#click:active {
  box-shadow:-1px -1px 20px var(--shadow-color);
}
#click:active::after {
  color: white;
}
#click::after {
  content: "Click Me!";
  position: absolute;
  top:35vh;
  left:0;
  text-align: center;
  width:80vh;
  font-size: 1.5em;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: sans-serif;
  flex-wrap: wrap;
}
html,body{
  height:100%;
}

#textDiv {
  font-size:1.2em;
  margin-left: 5em;
  width:20vw;
}
#clickCount::before {
  content: "Total Clicks: ";
}
#cps {
  font-size: 2em;
}
#cps::after {
  content: " cps";
  font-size: 0.6em;
}
#timeRemaining::before {
  content: "Time Remaining: ";
}
#slider-container {
  width:100vw;
}
#timeSlider {
  width: 10%;
}
#time::after {
  content: " seconds";
}
.single::after {
  content: " second" !important;
}
#time {
  text-align: center;
  width:10%;
  display: block;
}


label {
  vertical-align: middle;
}


#allTime::before {
  content: "All Time: ";
}




/* Input type=range styles from range.css */
input[type=range] {
  width: 100%;
  margin: 7.1px 0;
  background-color: transparent;
  -webkit-appearance: none;
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  background: #27466b;
  border: 0;
  border-radius: 5.4px;
  width: 100%;
  height: 10.8px;
  cursor: pointer;
}
input[type=range]::-webkit-slider-thumb {
  margin-top: -7.1px;
  width: 25px;
  height: 25px;
  background: rgba(28, 83, 255, 0.93);
  border: 2.9px solid #1812ff;
  border-radius: 29px;
  cursor: pointer;
  -webkit-appearance: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
  background: #2e527e;
}
input[type=range]::-moz-range-track {
  background: #27466b;
  border: 0;
  border-radius: 5.4px;
  width: 100%;
  height: 10.8px;
  cursor: pointer;
}
input[type=range]::-moz-range-thumb {
  width: 25px;
  height: 25px;
  background: rgba(28, 83, 255, 0.93);
  border: 2.9px solid #1812ff;
  border-radius: 29px;
  cursor: pointer;
}
input[type=range]::-ms-track {
  background: transparent;
  border-color: transparent;
  border-width: 8.9px 0;
  color: transparent;
  width: 100%;
  height: 10.8px;
  cursor: pointer;
}
input[type=range]::-ms-fill-lower {
  background: #203a58;
  border: 0;
  border-radius: 10.8px;
}
input[type=range]::-ms-fill-upper {
  background: #27466b;
  border: 0;
  border-radius: 10.8px;
}
input[type=range]::-ms-thumb {
  width: 25px;
  height: 25px;
  background: rgba(28, 83, 255, 0.93);
  border: 2.9px solid #1812ff;
  border-radius: 29px;
  cursor: pointer;
  margin-top: 0px;
  /*Needed to keep the Edge thumb centred*/
}
input[type=range]:focus::-ms-fill-lower {
  background: #27466b;
}
input[type=range]:focus::-ms-fill-upper {
  background: #2e527e;
}
/*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out
how to remove the virtical space around the range input in IE*/
@supports (-ms-ime-align:auto) {
  /* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */
  input[type=range] {
    margin: 0;
    /*Edge starts the margin from the thumb, not the track as other browsers do*/
  }
}
```
###JAVASCRIPT
```javascript
const click = document.getElementById("click");
const clickCountP = document.getElementById("clickCount");
let clickCount = 0;
const cps = document.getElementById("cps");
const timeRemaining = document.getElementById("timeRemaining");

const timeSlider = document.getElementById("timeSlider");
const timeText = document.getElementById("time");

timeSlider.oninput = ()=>{
  timeText.innerText = timeSlider.value;
  time = timeSlider.value;
  if(time == 1) {
    timeText.classList.add("single");
  } else if(timeText.classList.contains("single")) {
    timeText.classList.remove("single");
  }
}

let time = timeSlider.value;

let startTime = null;
const allTime = document.getElementById("allTime");
allTime.ondblclick = ()=>{
  localStorage.removeItem("all-time");
  updateAllTime(0);
}
const updateAllTime = (newScore)=>{
  console.log(newScore, Number(localStorage.getItem("all-time")));
  if(newScore > Number(localStorage.getItem("all-time"))) {
    localStorage.setItem("all-time", newScore.toString());
  }
  allTime.textContent = localStorage.getItem("all-time") || 0;
}
updateAllTime(0);

const showClicks = ()=>{
  clickCountP.innerText = clickCount;
}

showClicks();
const animFunc = ()=>{
  const elapsed = (Date.now() - startTime) * 0.001;
   if(elapsed < time) {
      cps.innerText = Math.round((clickCount / elapsed) * 10) / 10;
      timeRemaining.innerText = (time - elapsed).toFixed(2);
      window.requestAnimationFrame(animFunc);
   } else {
     click.disabled = true;
     cps.innerText = Math.round((clickCount / time) * 10) / 10;
     timeRemaining.innerText = 0;
     updateAllTime(Number(cps.innerText));
     cps.innerText = "Result: "+cps.innerText;
     startTime = null;
     click.classList.add("play-again");     
     setTimeout(()=>{
       click.disabled = false;
     }, 1000);
   }
 }
const clickHandler = ()=>{
   if(!startTime) {
     startTime = Date.now();
     window.requestAnimationFrame(animFunc);
     clickCount = 0;
     click.classList.remove("play-again");
   }
   clickCount++;
   showClicks();
}

click.addEventListener("mousedown", (event)=>{
  if(event.button == 0) {
    clickHandler();
  }
});
click.addEventListener("contextmenu", (event)=>{
  event.preventDefault();
  clickHandler();
});

const darkTheme = document.getElementById("darkTheme");
const isDarkTheme = localStorage.getItem("dark-theme") === "true";
darkThemeIfy.bind({checked: isDarkTheme})();
darkTheme.checked = isDarkTheme;

darkTheme.oninput = darkThemeIfy;
  
function darkThemeIfy() {
  if(this.checked) {
    document.body.style.setProperty("--bg-color", "black");
    document.body.style.setProperty("--text-color", "white");
    document.body.style.setProperty("--click-color", "rgb(180,180,180)");
    document.body.style.setProperty("--shadow-color", "white");
    localStorage.setItem("dark-theme", "true");
  } else {
    document.body.style.setProperty("--bg-color", "");
    document.body.style.setProperty("--click-color", "");
    document.body.style.setProperty("--text-color", "");
    document.body.style.setProperty("--shadow-color", "");
    localStorage.setItem("dark-theme", "false");
  }
}
```