Open In App

Building a Pomodoro Timer with VueJS

Last Updated : 09 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A Pomodoro Timer is a time management tool that helps individuals break work into the intervals traditionally 25 minutes in the length separated by the short breaks. This timer will allow users to start, stop and reset the timer as needed with the visually appealing user interface.

Prerequisites:

Approach

  • Initialization: We start by setting up the basic HTML structure for the timer interface. This includes elements for the displaying the timer, progress bar and buttons for controlling the timer.
  • Styling: We apply CSS styles to enhance the appearance of the timer interface. This includes the defining font styles, colors, button styles and layout adjustments to make the timer visually appealing and user-friendly.
  • Vue.js Setup: We use Vue.js to add dynamic behavior to the timer. Vue.js allows us to create reactive components and easily handle user interactions such as the button clicks and timer updates.
  • Data Management: We define the data properties in the Vue.js to manage the timer state. This includes the properties like the current time remaining, whether the timer is running or paused and width of the progress bar.
  • Timer Logic: We implement the timer logic using the JavaScript. This includes functions to start the timer, pause the timer, and reset the timer. We use setInterval() to decrement the time remaining every second and update the progress bar accordingly.
  • User Interaction: We handle user interactions with the timer buttons. When the user clicks the Start button the timer starts counting down. The Pause button allows the user to the pause the timer and Reset button resets the timer to its initial state.

Example: This example shows the implementation of the above-explained approach.

HTML
<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, 
                                   initial-scale=1.0">
    <title>The Pomodoro Timer</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f9f9f9;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        .container {
            text-align: center;
            border: 2px solid #4CAF50;
            border-radius: 20px;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            background-color: #fff;
        }
        .timer {
            font-size: 4rem;
            margin-bottom: 20px;
            color: #4CAF50;
        }
        .progress-bar {
            width: 70%;
            background-color: #ddd;
            border-radius: 20px;
            overflow: hidden;
            margin: 0 auto;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }
        .progress-bar .progress {
            background-color: #4CAF50;
            height: 20px;
            border-radius: 20px;
            transition: width 0.5s ease-in-out;
        }
        button {
            font-size: 1.5rem;
            padding: 10px 20px;
            margin: 20px;
            border: none;
            background-color: #4CAF50;
            color: #fff;
            cursor: pointer;
            border-radius: 5px;
            transition: background-color 0.3s ease;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }
        button:hover {
            background-color: #45a049;
        }
        .brand {
            font-size: 2rem;
            color: #4CAF50;
        }
        .reset-button {
            background-color: #ff5252;
        }
        .pause-button {
            background-color: #ffd600;
        }
    </style>
</head>
  
<body>
    <div class="container">
        <div class="brand">Pomodoro Timer</div>
        <div class="timer">{{ formatTime }}</div>
        <div class="progress-bar">
            <div class="progress"
                 :style="{ width: progressBarWidth }"></div>
        </div>
        <button @click="startTimer" 
                :disabled="isRunning">Start</button>
        <button @click="stopTimer" 
                :disabled="!isRunning"
                class="pause-button">Pause</button>
        <button @click="resetTimer" 
                class="reset-button">Reset</button>
    </div>
    <script src=
"https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        new Vue({
            el: '.container',
            data: {
                time: 1500,
                isRunning: false,
                progressBarWidth: '100%'
            },
            computed: {
                formatTime() {
                    let minutes = Math.floor(this.time / 60);
                    let seconds = this.time % 60;
                    return `${minutes.toString().padStart(2, '0')}:
                    ${seconds.toString().padStart(2, '0')}`;
                }
            },
            methods: {
                startTimer() {
                    this.isRunning = true;
                    this.timer = setInterval(() => {
                        if (this.time > 0) {
                            this.time--;
                            this.progressBarWidth = `${(this.time / 1500)
                                                     * 100}%`;
                        } else {
                            this.stopTimer();
                            alert('Time is up!');
                        }
                    }, 1000);
                },
                stopTimer() {
                    clearInterval(this.timer);
                    this.isRunning = false;
                },
                resetTimer() {
                    this.stopTimer();
                    this.time = 1500;
                    this.progressBarWidth = '100%';
                }
            }
        });
    </script>
</body>
  
</html>

Output:

po1



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads