About this Code
Hello reader, I am nilimadas. Nice to meet you again in this free code sharing website. In this post I am going to explain about cpc-Pomodoro_timer.
If you are new to this website, we recommend you to subscribe to our youtube channel and watch the videos. Ok lets dive into the code.
Images
These are the output images of the code. You can click on the image to enlarge it. also you can click the try it button to see the output.
Youtube Tutorial Video
If you are a visual learner and want to learn how to use this code, you can watch the video below.
and also this video contains the clear step by step explanation and the output of the code.
VIDEO
Source Code
This is the source code of the code. You can copy and paste the code to your editor.
@charset "UTF-8";
@import url(https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,600,700,800);
*,
:after,
:before {
box-sizing: border-box;
padding: 0;
margin: 0;
}
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
:root {
--dark-blue: hsl(236, 44%, 17%);
--dark-blue-light: hsl(236, 44%, 25%);
--very-dark-blue: hsl(235, 35%, 13%);
--blue-gray: hsl(236, 15%, 60%);
--light-blue-gray: hsl(236, 46%, 93%);
--light-white-gray: hsl(212, 22%, 73%);
--pink: hsl(300, 82%, 78%);
--theme-color: hsl(0, 84%, 68%);
}
.container.red {
--theme-color: hsl(340, 100%, 58%);
}
.container.green {
--theme-color: hsl(55, 100%, 50%);
}
.container.blue {
--theme-color: hsl(135, 98%, 50%);
}
body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 100vh;
background-color: var(--light-white-gray);
}
.container {
position: relative;
width: 450px;
height: 550px;
display: flex;
justify-content: center;
align-items: center;
/* flex-direction: column;
gap: 2rem; */
background: #c9d5e0;
border-radius: 50px;
border-top-left-radius: 250px;
border-top-right-radius: 250px;
box-shadow: 45px 45px 45px -15px rgba(0, 0, 0, 0.15),
inset 15px 15px 10px rgba(255, 255, 255, 0.75),
-15px -15px 35px rgba(255, 255, 255, 0.55),
inset -2px -2px 15px rgba(0, 0, 0, 0.2);
}
/* .logo{
} */
/* */
.timer-container {
position: absolute;
top: 30px;
width: 390px;
height: 390px;
background-color: var(--very-dark-blue);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 7px 7px 22px #152b4a66, inset 7px 7px 7px rgba(255, 255, 255, 0.55),
-9px -9px 15px rgba(255, 255, 255, 1);
}
.timer-content {
width: 90%;
height: 90%;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
/* border: 8px solid var(--theme-color); */
transition: 0.4s;
}
.timer-content h2 {
font-size: 4rem;
font-weight: 600;
padding: 0.5rem;
color: var(--theme-color);
}
#timer {
font-size: 4rem;
border-radius: 40px;
font-weight: 600;
border-radius: 40px;
background-color: var(--very-dark-blue);
box-shadow: 7px 7px 22px #152b4a66, inset 7px 7px 7px rgba(7, 6, 6, 0.55),
-9px -9px 15px rgb(17, 1, 1);
}
.timer-content button {
border: none;
background-color: transparent;
color: var(--blue-gray);
padding: 1rem;
letter-spacing: 10px;
cursor: pointer;
}
#config {
background-color: transparent;
border: none;
cursor: pointer;
position: absolute;
bottom: 35px;
}
#config img {
width: 24px;
}
/* */
.option-btn-container {
padding: 0.5rem;
background-color: var(--very-dark-blue);
border-radius: 32px;
display: flex;
flex-wrap: nowrap;
position: absolute;
bottom: 50px;
}
.option-btn {
padding: 0.75rem 1.25rem;
border: none;
border-radius: 24px;
font-weight: bold;
background-color: transparent;
color: var(--blue-gray);
cursor: pointer;
transition: 0.4s;
}
.option-btn.active-option-btn {
background-color: var(--theme-color);
color: var(--dark-blue);
}
/* SETTING MODAL */
.hidden {
display: none;
}
.settings-modal {
max-width: 450px;
padding: 1.5rem 1.5rem 3rem 1.5rem;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--light-blue-gray);
border-radius: 24px;
color: var(--dark-blue);
z-index: 10;
}
.settings-modal .header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.settings-modal .header #closeBtn {
padding: 0.25rem;
background-color: transparent;
border: none;
font-size: 1.25rem;
font-weight: bold;
color: var(--blue-gray);
cursor: pointer;
}
.settings-modal h4 {
margin-bottom: 0.75rem;
}
.settings-modal form {
display: flex;
align-items: center;
justify-content: space-between;
}
.settings-modal form .input-container {
width: 33.3%;
}
.settings-modal form label {
margin-top: 0.5rem;
font-size: 0.75rem;
color: var(--blue-gray);
}
.settings-modal form input {
max-width: 95%;
padding: 0.5rem;
height: 42px;
border: none;
border-radius: 8px;
background-color: var(--light-blue-gray);
font-weight: bold;
color: var(--dark-blue);
}
.settings-modal form input:focus {
outline: 1px solid var(--blue-gray);
}
.settings-modal #apply {
position: absolute;
bottom: -24px;
left: 50%;
transform: translateX(-50%);
background-color: var(--dark-blue);
color: white;
font-weight: bold;
padding: 0.75rem 1.5rem;
border-radius: 24px;
border: none;
cursor: pointer;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(3px);
z-index: 5;
}
console.log("Event Fired")
const timerEl = document.getElementById("timer");
const playPause = document.getElementById("playPause");
const container = document.querySelector(".container");
const optionBtnContainer = document.querySelector(".option-btn-container");
const optionBtns = document.querySelectorAll(".option-btn");
const audio = new Audio("sound.mp3");
// Modal
const configBtn = document.getElementById("config");
const closeBtn = document.getElementById("closeBtn");
const applyBtn = document.getElementById("apply");
const settingsModal = document.querySelector(".settings-modal");
const overlay = document.querySelector(".overlay");
const pomodoroInput = document.getElementById("pomodoroInput");
const shortBreakInput = document.getElementById("shortBreakInput");
const longBreakInput = document.getElementById("longBreakInput");
// Presets
const timersSettings = {
pomodoro: {
name: "pomodoro",
time: 1500,
classe: "red"
},
shortBreak: {
name: "shortBreak",
time: 300,
classe: "green"
},
longBreak: {
name: "longBreak",
time: 900,
classe: "blue"
}
};
let currentTimerInterval,
currentTimerSetting,
definedTime,
timerIsRunning,
round,
maxRound;
// Functions
const updateTimerEl = function () {
const min = String(Math.trunc(definedTime / 60)).padStart(2, 0);
const sec = String(Math.trunc(definedTime % 60)).padStart(2, 0);
timerEl.innerHTML = `${min}:${sec}`;
};
const getSettingsStored = function () {
const timersSettingsStored = JSON.parse(
localStorage.getItem("timersSettings")
);
if (!timersSettingsStored) return;
timersSettings.pomodoro.time = timersSettingsStored.pomodoro.time;
timersSettings.shortBreak.time = timersSettingsStored.shortBreak.time;
timersSettings.longBreak.time = timersSettingsStored.longBreak.time;
pomodoroInput.value = timersSettings.pomodoro.time / 60;
shortBreakInput.value = timersSettings.shortBreak.time / 60;
longBreakInput.value = timersSettings.longBreak.time / 60;
};
const init = function () {
getSettingsStored();
currentTimerSetting = timersSettings.pomodoro;
definedTime = currentTimerSetting.time;
updateTimerEl();
timerIsRunning = false;
round = 0;
maxRound = 4;
};
init();
const resetTimer = function () {
clearInterval(currentTimerInterval);
timerIsRunning = false;
playPause.innerHTML = "PLAY";
container.classList.remove("red", "green", "blue");
optionBtns.forEach((btn) => btn.classList.remove("active-option-btn"));
};
const changeTimerInterface = function (id) {
currentTimerSetting = timersSettings[id];
definedTime = timersSettings[id].time;
document.getElementById(`${id}`).classList.add("active-option-btn");
container.classList.add(timersSettings[id].classe);
updateTimerEl();
};
const startTimer = function () {
const tick = function () {
definedTime--;
updateTimerEl();
if (definedTime === 0) {
audio.play();
resetBtn();
if (currentTimerSetting === timersSettings.pomodoro) {
round++;
if (round >= maxRound) {
maxRound += 4;
changeTimerInterface("longBreak");
} else {
changeTimerInterface("shortBreak");
}
} else {
changeTimerInterface("pomodoro");
}
}
};
timerIsRunning = true;
tick();
const timer = setInterval(tick, 1000);
return timer;
};
// Event handlers
playPause.addEventListener("click", function () {
if (!timerIsRunning) {
currentTimerInterval = startTimer();
playPause.innerHTML = "PAUSE";
} else {
clearInterval(currentTimerInterval);
timerIsRunning = false;
playPause.innerHTML = "PLAY";
}
});
optionBtnContainer.addEventListener("click", function (e) {
if (e.target.classList.contains("option-btn")) {
resetTimer();
e.target.classList.add("active-option-btn");
changeTimerInterface(e.target.id);
}
});
// Setting Modal
configBtn.addEventListener("click", function () {
settingsModal.classList.remove("hidden");
overlay.classList.remove("hidden");
});
const closeModal = function () {
settingsModal.classList.add("hidden");
overlay.classList.add("hidden");
};
closeBtn.addEventListener("click", closeModal);
overlay.addEventListener("click", closeModal);
document.addEventListener("keydown", function (e) {
if (e.key == "Escape" && !settingsModal.classList.contains("hidden"))
closeModal();
});
applyBtn.addEventListener("click", function () {
timersSettings.pomodoro.time = Number(pomodoroInput.value) * 60;
timersSettings.shortBreak.time = Number(shortBreakInput.value) * 60;
timersSettings.longBreak.time = Number(longBreakInput.value) * 60;
localStorage.setItem("timersSettings", JSON.stringify(timersSettings));
changeTimerInterface(currentTimerSetting.name);
closeModal();
});
And also you can click the try it button to see the output of the code in our web Code Playground.
You can also download the code to the zip format by clicking the download button. The download process is little bit complex, you need ti await for 10 seconds. after that you can download the code by clicking the generated download link.
Leave a Comment
You need to login first to comment.