🎮ArcadeLab

Click Speed Test

by MegaFlare51
555 lines8.9 KB
▶ Play
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Click Speed Test</title>

<style>
*{
  box-sizing:border-box;
}

body{
  margin:0;
  min-height:100vh;
  font-family:Arial,sans-serif;
  background:linear-gradient(135deg,#07111f,#102a56);
  color:white;
  padding:15px;
}

.app{
  width:min(650px,100%);
  margin:auto;
}

header{
  text-align:center;
  padding:15px 0 20px;
}

h1{
  margin:0;
  font-size:34px;
}

.sub{
  color:#aebdd3;
  margin-top:8px;
}

.modos{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:8px;
  margin-bottom:15px;
}

.modo{
  border:0;
  border-radius:12px;
  padding:14px 4px;
  background:#243653;
  color:white;
  font-size:16px;
  font-weight:bold;
}

.modo.ativo{
  background:#2875f0;
}

.painel{
  background:#101d32;
  border-radius:22px;
  padding:22px 16px;
  text-align:center;
  box-shadow:0 10px 35px rgba(0,0,0,.35);
}

.tempo{
  color:#8fb9ff;
  font-size:22px;
}

.contador{
  font-size:75px;
  font-weight:bold;
  margin:5px 0;
}

.cps{
  color:#c5d3e8;
  font-size:21px;
  margin-bottom:20px;
}

#clicar{
  width:100%;
  height:180px;
  border:0;
  border-radius:22px;
  background:#2875f0;
  color:white;
  font-size:30px;
  font-weight:bold;
  box-shadow:0 8px 0 #174b9e;
  touch-action:manipulation;
  user-select:none;
}

#clicar:active{
  transform:translateY(6px);
  box-shadow:0 2px 0 #174b9e;
}

#clicar:disabled{
  opacity:.45;
}

.iniciar{
  width:100%;
  margin-top:20px;
  padding:15px;
  border:0;
  border-radius:13px;
  background:#18a957;
  color:white;
  font-size:19px;
  font-weight:bold;
}

.resultado{
  margin-top:20px;
  padding:18px;
  background:#182942;
  border-radius:15px;
  display:none;
}

.resultado .numero{
  font-size:34px;
  font-weight:bold;
}

.secao{
  margin-top:18px;
  background:#101d32;
  padding:18px;
  border-radius:18px;
}

.secao h2{
  margin-top:0;
  font-size:21px;
}

.recordes{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:10px;
}

.record{
  background:#1b2b45;
  border-radius:12px;
  padding:14px;
  text-align:center;
}

.record b{
  display:block;
  font-size:18px;
  margin-bottom:6px;
}

.record span{
  font-size:24px;
  font-weight:bold;
}

.historico{
  max-height:300px;
  overflow:auto;
}

.item{
  background:#1b2b45;
  padding:12px;
  border-radius:10px;
  margin-bottom:8px;
  display:flex;
  justify-content:space-between;
  gap:10px;
}

.item strong{
  color:#8fb9ff;
}

.vazio{
  text-align:center;
  color:#8292aa;
}

.apagar{
  width:100%;
  margin-top:12px;
  padding:12px;
  border:0;
  border-radius:11px;
  background:#b4232d;
  color:white;
  font-weight:bold;
}

@media(max-width:420px){

  h1{
    font-size:28px;
  }

  .contador{
    font-size:60px;
  }

  #clicar{
    height:165px;
    font-size:27px;
  }

  .recordes{
    grid-template-columns:1fr 1fr;
  }
}
</style>
</head>

<body>

<div class="app">

<header>
  <h1>⚡ CLICK SPEED</h1>
  <div class="sub">Teste sua velocidade de cliques</div>
</header>

<div class="modos">
  <button class="modo ativo" onclick="escolherTempo(5,this)">5s</button>
  <button class="modo" onclick="escolherTempo(10,this)">10s</button>
  <button class="modo" onclick="escolherTempo(15,this)">15s</button>
  <button class="modo" onclick="escolherTempo(20,this)">20s</button>
</div>

<div class="painel">

  <div class="tempo">
    ⏱️ <span id="tempo">5.00</span>s
  </div>

  <div class="contador" id="contador">0</div>

  <div class="cps">
    CPS: <span id="cps">0.00</span>
  </div>

  <button id="clicar" disabled>
    👆 CLIQUE AQUI
  </button>

  <button class="iniciar" onclick="iniciar()">
    🚀 INICIAR TESTE
  </button>

  <div class="resultado" id="resultado">
    🏆 RESULTADO
    <br><br>

    <span class="numero" id="finalCliques">0</span>
    cliques

    <br>

    <span id="finalCps">0.00</span> CPS
  </div>

</div>

<div class="secao">

  <h2>🏆 Recordes</h2>

  <div class="recordes">

    <div class="record">
      <b>5 segundos</b>
      <span id="record5">0</span>
      <small>CPS: <span id="record5cps">0.00</span></small>
    </div>

    <div class="record">
      <b>10 segundos</b>
      <span id="record10">0</span>
      <small>CPS: <span id="record10cps">0.00</span></small>
    </div>

    <div class="record">
      <b>15 segundos</b>
      <span id="record15">0</span>
      <small>CPS: <span id="record15cps">0.00</span></small>
    </div>

    <div class="record">
      <b>20 segundos</b>
      <span id="record20">0</span>
      <small>CPS: <span id="record20cps">0.00</span></small>
    </div>

  </div>

</div>

<div class="secao">

  <h2>📜 Histórico</h2>

  <div class="historico" id="historico"></div>

  <button class="apagar" onclick="apagarHistorico()">
    🗑️ APAGAR HISTÓRICO
  </button>

</div>

</div>

<script>

let duracao = 5;
let cliques = 0;
let iniciado = false;
let inicio = 0;
let intervalo = null;

const botao = document.getElementById("clicar");

botao.addEventListener("pointerdown", function(e){

  e.preventDefault();

  if(iniciado){
    cliques++;
    document.getElementById("contador").textContent = cliques;
  }

});

function escolherTempo(segundos, elemento){

  if(iniciado) return;

  duracao = segundos;

  document.querySelectorAll(".modo")
    .forEach(b => b.classList.remove("ativo"));

  elemento.classList.add("ativo");

  document.getElementById("tempo").textContent =
    duracao.toFixed(2);
}

function iniciar(){

  clearInterval(intervalo);

  cliques = 0;
  iniciado = true;
  inicio = performance.now();

  document.getElementById("contador").textContent = "0";
  document.getElementById("cps").textContent = "0.00";
  document.getElementById("resultado").style.display = "none";

  botao.disabled = false;

  intervalo = setInterval(atualizar,10);
}

function atualizar(){

  if(!iniciado) return;

  const agora = performance.now();

  const passado = (agora - inicio) / 1000;

  const restante = Math.max(
    0,
    duracao - passado
  );

  document.getElementById("tempo").textContent =
    restante.toFixed(2);

  const cpsAtual =
    cliques / Math.max(passado,0.001);

  document.getElementById("cps").textContent =
    cpsAtual.toFixed(2);

  if(passado >= duracao){
    terminar();
  }
}

function terminar(){

  if(!iniciado) return;

  iniciado = false;

  clearInterval(intervalo);

  botao.disabled = true;

  const resultadoCps = cliques / duracao;

  document.getElementById("tempo").textContent = "0.00";

  document.getElementById("cps").textContent =
    resultadoCps.toFixed(2);

  document.getElementById("finalCliques").textContent =
    cliques;

  document.getElementById("finalCps").textContent =
    resultadoCps.toFixed(2);

  document.getElementById("resultado").style.display =
    "block";

  salvarResultado();
}

function salvarResultado(){

  let historico =
    JSON.parse(localStorage.getItem("clickHistorico") || "[]");

  const registro = {
    tempo: duracao,
    cliques: cliques,
    cps: Number((cliques / duracao).toFixed(2)),
    data: new Date().toLocaleString("pt-BR")
  };

  historico.unshift(registro);

  localStorage.setItem(
    "clickHistorico",
    JSON.stringify(historico)
  );

  atualizarRecordes();
  mostrarHistorico();
}

function atualizarRecordes(){

  const historico =
    JSON.parse(localStorage.getItem("clickHistorico") || "[]");

  [5,10,15,20].forEach(segundos => {

    const testes =
      historico.filter(x => x.tempo === segundos);

    if(testes.length === 0){

      document.getElementById(
        "record" + segundos
      ).textContent = "0";

      document.getElementById(
        "record" + segundos + "cps"
      ).textContent = "0.00";

      return;
    }

    const melhor =
      testes.reduce((a,b) =>
        b.cliques > a.cliques ? b : a
      );

    document.getElementById(
      "record" + segundos
    ).textContent = melhor.cliques;

    document.getElementById(
      "record" + segundos + "cps"
    ).textContent =
      melhor.cps.toFixed(2);
  });
}

function mostrarHistorico(){

  const area =
    document.getElementById("historico");

  const historico =
    JSON.parse(localStorage.getItem("clickHistorico") || "[]");

  if(historico.length === 0){

    area.innerHTML =
      '<div class="vazio">Nenhum teste realizado ainda.</div>';

    return;
  }

  area.innerHTML =
    historico.map((item,index) => `

      <div class="item">

        <div>
          <strong>${item.tempo}s</strong><br>
          ${item.cliques} cliques
        </div>

        <div>
          <strong>${item.cps.toFixed(2)} CPS</strong><br>
          <small>${item.data}</small>
        </div>

      </div>

    `).join("");
}

function apagarHistorico(){

  if(!confirm("Apagar todos os resultados salvos?")){
    return;
  }

  localStorage.removeItem("clickHistorico");

  atualizarRecordes();
  mostrarHistorico();

  document.getElementById("resultado").style.display =
    "none";
}

atualizarRecordes();
mostrarHistorico();

</script>

</body>
</html>

Game Source: Click Speed Test

Creator: MegaFlare51

Libraries: none

Complexity: complex (555 lines, 8.9 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: click-speed-test-megaflare51" to link back to the original. Then publish at arcadelab.ai/publish.