Comment construire un Pomodoro en JavaScript
Tags: javascript, webdev, css, html
Published: 2022-12-16 14:29:15

****

La méthode Pomodoro aide à la gestion du temps et consiste à travailler en 25 minutes chronométrées et à faire une pause de 5 minutes. Un minuteur extériorise la discipline et vous aide à vous tenir responsable. Dans ce tutoriel, nous allons apprendre à le construire en utilisant html, css et javascript. Retrouvez le code complet et le résultat [ici](https://github.com/Bonheur93/Pomodoro-timer-js.git) en suivant les étapes suivantes :

1.Créez un dossier qui contiendra notre projet, vous pouvez le nommer comme vous voulez mais pour nous, nous le nommerons pomodoro-timer. A l'intérieur de notre dossier pomodoro-timer, créons trois fichiers : `index.html`, qui contiendra le template de notre projet ; `style.css` pour les styles et `sript.js` javascrpt logic. Ouvrez-les ensuite avec un éditeur de texte. Dans ce tutoriel, nous allons utiliser VS Code.

Plongeons maintenant dans le projet. Tout d'abord, nous allons créer notre document html dans le fichier `index.html`.

```
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pomodoro Timer</title>

    <!-- FONT -->
    <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=Open+Sans:wght@300;400;600&display=swap" rel="stylesheet">

    <!-- ICONS links -->
    <script src="https://kit.fontawesome.com/6f3103b13c.js" crossorigin="anonymous"></script>

    <!-- CSS Links -->
    <link rel="stylesheet" href="./style.css">


</head>

<body>
    <section>
        <div class="container">
            <h1>POMODORO TIMER</h1>

            <div class="painel">
                <p id="work">work</p>
                <p id="break">break</p>
            </div>

            <div class="timer">
                <div class="circle">
                    <div class="time">
                        <p id="minutes"></p>
                        <p>:</p>
                        <p id="seconds"></p>
                    </div>
                </div>
            </div>

            <div class="controls">
                <button id="start" onclick="start()"><i class="fa-solid fa-play"></i></button>
        
                <a id="reset" href="./"><i class="fa-solid fa-arrow-rotate-left"></i></a>
            </div>
        </div>
    </section>

    <!-- SCRIPT -->
    <script src="./script.js"></script>
</body>

</html>

```
2. Alors ajoutons maintenant quelques styles pour le rendre présentable dans le fichier index.css.

```
:root {
    font-size: 62.5%; /* 1rem = 10px */

    --color-primary: hsl(235, 70%, 67%);
    --color-secondary: hsl(358, 78%, 69%);
    --color-font: hsla(0, 0%, 100%, 0.902);

    --color-shadow: hsl(235, 36%, 35%);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html, body {
    height: 100%;
    background-color: var(--color-primary);
    font-size: 1.6rem;
    font-family: 'Open sans', sans-serif;
}

p,
i,
h1 {
    color: var(--color-font);
}

i {
    font-size: 3.2rem;
}

h1 {
    font-size: 3.2rem;
}

/* ==== CONTENT ==== */

section {
    display: flex;
    align-items: center;
    height: 100%;
}

.container {
    width: min(42.5rem, 100%);
    margin-inline: auto;
    padding-inline: 2rem;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}

.painel {
    display: grid;
    grid-template-columns: 1fr 1fr;
    text-align: center;
    width: 20rem;
    margin-block: 5rem;
    padding: 1rem;
    border-radius: 10rem;
    -webkit-box-shadow: 0px 0px 15px 10px var(--color-shadow); 
    box-shadow: 0px 0px 15px 10px var(--color-shadow);
}

.painel p {
    opacity: .8;
    transition: 1s ease-in;
}

.painel p.active {
    opacity: 1;
    color: var(--color-secondary);
}

.timer {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 30rem;
    height: 30rem;
    border-radius: 50%;
    -webkit-box-shadow: 0px 0px 15px 10px var(--color-shadow); 
    box-shadow: 0px 0px 15px 10px var(--color-shadow);
}

.circle {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 26rem;
    height: 26rem;
    border-radius: 50%;
    background-color: var(--color-secondary); 
    position: relative;
}

.circle::before {
    content: '';
    position: absolute;
    width: 95%;
    height: 95%;
    border-radius: 50%;
    background-color: var(--color-primary);
}

.time {
    position: relative;
    display: flex;
    flex-direction: row;
}

.time p {
    font-size: 5.6rem;
}

.time p:nth-of-type(2) {
    position: relative;
    top: -.5rem;
    margin-inline: 1rem;
}

.controls {
    margin-top: 3rem;
}

.controls button {
    border: none;
    background-color: transparent;
    cursor: pointer;
}

.controls #reset {
    display: none;
}
button{
    color: red;
}
```

Cela devrait donner quelque chose comme ceci

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3chvn6k910mmjpf7mh2f.png)

3. Il est maintenant temps d'ajouter la logique javascript et de commencer à décrémenter le temps avec un événement de clic. Pour accéder aux balises html, nous allons uliliser le secteur js querySelector en ciblant les ids que nous avons attachés aux balises html et nous allons initialiser nos variable selon les valeurs qui serons utiliser plus tard. Voyons comment faire cela dans le code ci-dessous

```
// variables

let workTittle = document.getElementById('work');
let breakTittle = document.getElementById('break');

let workTime = 25;
let breakTime = 5;

let seconds = "00"
```

4. Nous allons maintenant sélectionner nos deux partie d'affichage de temps avec son intervalle d’exécution, clairement nous avons les minutes et les secondes.

```
window.onload = () => {
    document.getElementById('minutes').innerHTML = workTime;
    document.getElementById('seconds').innerHTML = seconds;

    workTittle.classList.add('active');
}

let minute = 100;
setInterval(() => {
    if(minute >=0){
        document.getElementsByClassName("circle").style.width = minute;
        minute--;
    }
}, 600);

```

5. C'est dans cette partie que nous allons donc créer une fonction permettant de faire fonctionner nos deux boutons (Play et reload) qui exécute le comptage à rebours des secondes et minutes. 

```

// start timer
function start() {
    // change button
    document.getElementById('start').style.display = "none";
    document.getElementById('reset').style.display = "block";

    // change the time
    seconds = 59;

    let workMinutes = workTime - 1;
    let breakMinutes = breakTime - 1;

    breakCount = 0;

    // countdown
    let timerFunction = () => {
        //change the display
        document.getElementById('minutes').innerHTML = workMinutes;
        document.getElementById('seconds').innerHTML = seconds;

        // start
        seconds = seconds - 1;

        if(seconds === 0) {
            workMinutes = workMinutes - 1;
            if(workMinutes === -1 ){
                if(breakCount % 2 === 0) {
                    // start break
                    workMinutes = breakMinutes;
                    breakCount++

                    // change the painel
                    workTittle.classList.remove('active');
                    breakTittle.classList.add('active');
                }else {
                    // continue work
                    workMinutes = workTime;
                    breakCount++

                    // change the painel
                    breakTittle.classList.remove('active');
                    workTittle.classList.add('active');
                }
            }
            seconds = 59;
        }
    }

    // start countdown
    setInterval(timerFunction, 1000); // 1000 = 1s
}
```
Et donc maintenant vous êtes prêt à appliquer les principes du pomodoro puisque vous êtes capable d'en faire un par vous-même. Nous restons ouvert à toutes les questions concernant le sujet! à très bientôt!