[Download] Construa o Seu Próprio Cronometro Online com HTML, CSS e JS - Bruno Devx - BR Criativus

post #4928

[Download] Construa o Seu Próprio Cronometro Online com HTML, CSS e JS

Publicado em: 23/04/2024 / Atualizado em: 27/06/2026

Categorias: BlogCSSHTMLJavaScript (JS)JS

Neste artigo vou disponibilizar todo o código de um cronometro online que usa pouco código HTML, CSS e JavaScript para rodar. Ele pode ser instalado facilmente em qualquer hospedagem simples, e roda muito bem.

Você pode testar ele online neste link: https://tools.webmaster.dev.br/cronometro-online/

Segue os códigos abaixo para estudo e implementação:

Arquivo (index.html):

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contador Online</title>
    <link rel="stylesheet" href="style.css?v=1.1.1">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/confetti.browser.min.js"></script>
</head>
<body>
    
<div class="container">
    <h1>Cronometro Online</h1>
    <div id="display">00:00:00:000</div>
    <div class="buttons">
        <button id="startButton">Iniciar</button>
        <button id="pauseButton" style="display: none;">Pausar</button>
    </div>
    <div id="commentSection" style="display: none;">
        <textarea id="commentText" placeholder="Adicione um comentario..."></textarea>
        <button id="saveTime">Salvar Tempo</button>
    </div>
    <div id="headerSaveTimes" class="headerSaveTimes">
        <div class="title">Tempos salvos:</div>
        <button id="removeAll">Remover Todos</button>
    </div>
    <ul id="savedTimes"></ul>
</div>

<script src="script.js?v=1.1.1"></script>
</body>
</html>

Arquivo (script.js):

let startTime;
let elapsed = 0;
let interval;
const display = document.getElementById('display');
const startButton = document.getElementById('startButton');
const pauseButton = document.getElementById('pauseButton');
const commentSection = document.getElementById('commentSection');
const saveTimeButton = document.getElementById('saveTime');
const removeAllButton = document.getElementById('removeAll');
const savedTimesList = document.getElementById('savedTimes');
const headerSaveTimes = document.getElementById('headerSaveTimes');


// Carrega os tempos salvos quando a página é carregada
document.addEventListener("DOMContentLoaded", () => {
    loadSavedTimes();
});

function updateDisplay(time) {
    let milissegundos = time % 1000;
    let segundos = Math.floor(time / 1000) % 60;
    let minutos = Math.floor(time / 60000) % 60;
    let horas = Math.floor(time / 3600000);
    display.textContent = 
        `${horas.toString().padStart(2, '0')}:${minutos.toString().padStart(2, '0')}:${segundos.toString().padStart(2, '0')}:${milissegundos.toString().padStart(3, '0')}`;
}

function startTimer() {
    if (!interval) {
        startTime = Date.now() - elapsed;
        interval = setInterval(() => {
            elapsed = Date.now() - startTime;
            updateDisplay(elapsed);
        }, 10);
    }
}

function stopTimer() {
    clearInterval(interval);
    interval = null;
}

startButton.addEventListener('click', function() {
    if (startButton.textContent === "Iniciar") {
        startTimer();
        startButton.textContent = "Resetar";
        pauseButton.style.display = "inline";
        pauseButton.textContent = "Pausar";
        commentSection.style.display = 'none';  // Esconder a seção de comentário ao iniciar
    } else { // Resetar
        elapsed = 0;
        updateDisplay(0);
        stopTimer();
        startButton.textContent = "Iniciar";
        pauseButton.style.display = "none";
    }
});

pauseButton.addEventListener('click', function() {
    if (pauseButton.textContent === "Pausar") {
        stopTimer();
        pauseButton.textContent = "Continuar";
        commentSection.style.display = 'block';  // Mostrar a seção de comentário ao pausar
        fireConfetti();
    } else { // Continuar
        startTimer();
        pauseButton.textContent = "Pausar";
        commentSection.style.display = 'none';  // Esconder a seção de comentário ao continuar
    }
});

function fireConfetti() {
    confetti({
        particleCount: 100,
        spread: 70,
        origin: { y: 0.6 }
    });
}

saveTimeButton.addEventListener('click', function() {
    const commentText = document.getElementById('commentText').value;
    const time = display.textContent;
    const savedTimes = JSON.parse(sessionStorage.getItem('savedTimes')) || [];
    savedTimes.push({ time, comment: commentText });
    sessionStorage.setItem('savedTimes', JSON.stringify(savedTimes));
    addTimeToList(time, commentText, savedTimes.length - 1);
    document.getElementById('commentText').value = ''; // Limpar caixa de texto após salvar
});

removeAllButton.addEventListener('click', function() {
    sessionStorage.removeItem('savedTimes');
    savedTimesList.innerHTML = ''; // Limpa a lista na interface
    updateHeaderVisibility();
});

function addTimeToList(time, comment, index) {
    const li = document.createElement('li');
    li.innerHTML = `<div style="position: relative; z-index: 1;"><strong>${time}</strong> - ${comment}</div>`;
    const removeBtn = document.createElement('button');
    removeBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="18" fill="currentColor" viewBox="0 0 24 26"><path fill-rule="evenodd" d="M2.515 8.638a.875.875 0 0 1 1.013.71l2.328 13.238a1.458 1.458 0 0 0 1.436 1.206h9.416c.708 0 1.314-.509 1.436-1.206l2.328-13.238a.875.875 0 0 1 1.723.304l-2.327 13.237a3.208 3.208 0 0 1-3.16 2.653H7.292a3.208 3.208 0 0 1-3.16-2.653L1.805 9.652a.875.875 0 0 1 .71-1.014Zm7.881-6.43c-.806 0-1.459.653-1.459 1.459v1.458h6.126V3.667c0-.806-.653-1.459-1.459-1.459h-3.208Zm6.416 2.917V3.667A3.208 3.208 0 0 0 13.604.458h-3.208a3.208 3.208 0 0 0-3.209 3.209v1.458H1.5a.875.875 0 1 0 0 1.75h21a.875.875 0 0 0 0-1.75h-5.688Z" clip-rule="evenodd"/></svg>';
    removeBtn.className = 'remove';
    removeBtn.onclick = () => removeTime(index);
    li.appendChild(removeBtn);
    savedTimesList.appendChild(li);
    updateHeaderVisibility();
}

function removeTime(index) {
    const savedTimes = JSON.parse(sessionStorage.getItem('savedTimes')) || [];
    const itemToRemove = savedTimesList.children[index];

    if (itemToRemove) {
        itemToRemove.classList.add('collapsing');
        itemToRemove.addEventListener('animationend', () => {
            savedTimes.splice(index, 1);
            sessionStorage.setItem('savedTimes', JSON.stringify(savedTimes));
            updateListDisplay(); // Redesenha a lista após a remoção
        });
    }
}


function updateListDisplay() {
    savedTimesList.innerHTML = '';
    const savedTimes = JSON.parse(sessionStorage.getItem('savedTimes')) || [];
    savedTimes.forEach((item, index) => addTimeToList(item.time, item.comment, index));
    updateHeaderVisibility();
}

function loadSavedTimes() {
    const savedTimes = JSON.parse(sessionStorage.getItem('savedTimes')) || [];
    savedTimes.forEach((item, index) => addTimeToList(item.time, item.comment, index));
    updateHeaderVisibility();
}

function updateHeaderVisibility() {
    const hasItems = savedTimesList.children.length > 0;
    headerSaveTimes.style.display = hasItems ? 'flex' : 'none';
}

Arquivo (style.css):

/* style.css */
body, html {
    height: 100%;
    margin: 0;
    font-family: 'DM Mono', monospace;
    background-color: #f5f5f5;
    display: flex;
    justify-content: center;
    align-items: center;
}

.container {
    text-align: center;
    background-color: #ffffff;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    width: 300px;
}

h1 {
    font-size: 24px;
    margin-bottom: 20px;
}

#display {
    font-size: 40px;
    font-weight: 400;
    margin-bottom: 20px;
    color: #333333;
}

.buttons {
    display: flex;
    justify-content: space-around;
    flex-direction: row;
    align-items: center;
    gap: 16px;
}

.buttons button, button#saveTime, button.remove, button#removeAll {
    padding: 10px 20px;
    font-size: 16px;
    margin: 5px 0;
    cursor: pointer;
    border: none;
    border-radius: 5px;
    outline: none;
    transition: background-color 0.3s ease;
    color: #818181;
    width: 100%;
}

.buttons button#startButton {
    background: #0001ff;
    color: #fff;
}

.buttons button#startButton:hover {
    background: #0001fb;
    color: #fff;
}

.buttons button:hover, button#saveTime:hover, button#removeAll:hover {
    background-color: #d2d2d2;
    color: #747474;
}

textarea {
    width: 100%;
    height: 60px;
    margin-top: 10px;
    padding: 10px;
    box-sizing: border-box;
    border-radius: 5px;
    border: 1px solid #ccc;
    resize: none;
    font-size: 16px;
    color: #333;
    background-color: #fff;
}

textarea:focus {
    border-color: #007BFF;
    box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}

ul {
    list-style-type: none;
    padding: 0;
}

li {
    text-align: left;
    padding: 8px;
    margin-top: 5px;
    background-color: #eee;
    border-radius: 5px;
    font-size: 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

button#removeAll {
    background-color: transparent;
    color: #818181;
    margin: 0;
    width: auto;
}

button#removeAll:hover {
    background-color: #ffe6e6;
    color: #ff4343;
}

button.remove {
    padding: 8px;
    margin: 0;
    width: auto;
    opacity: 0.3;
}

button.remove:hover, button.remove:focus {
    background: #ffe6e6;
    opacity: 1;
    color: #ff4343;
}

.headerSaveTimes {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 16px;
}

@keyframes popIn {
    0% {
        transform: scale(0.5);
        opacity: 0;
    }
    50% {
        transform: scale(1.2);
        opacity: 0.5;
    }
    100% {
        transform: scale(1);
        opacity: 1;
    }
}

@keyframes ripple {
    0% {
        box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.7);
    }
    100% {
        box-shadow: 0 0 0 10px rgba(0, 123, 255, 0);
    }
}

li {
    animation: popIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    position: relative;
    overflow: hidden;
}

li::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 150%;
    height: 150%;
    background-color: rgba(0, 123, 255, 0.5);
    transform: translate(-50%, -50%) scale(0);
    border-radius: 50%;
    z-index: 0;
    animation: ripple 0.6s ease-out forwards;
}

@keyframes collapse {
    0% {
        transform: scale(1);
        opacity: 1;
        height: auto;
    }
    100% {
        transform: scale(0);
        opacity: 0;
        height: 0;
        padding: 0;
        margin: 0;
    }
}

li.collapsing {
    animation: collapse 0.5s ease-in forwards;
}

li.dragging {
    opacity: 0.5;
}

li.over {
    border: 2px dashed #000;
}

Este tipo de ferramenta ajuda a você a controlar e monitorar o tempo gasto de maneira intuitiva, e também disponibiliza uma maneira de salvar (temporariamente) o seu tempo, adicionando um nome para cada tempo contabilizado.

Publicações recomendadas:



Sugira uma publicação

Envie uma mensagem e sugira um publicação sobre um assunto que tenha dificuldades de resolver.

Clique aqui e entre em contato