Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ChrisShank/5a49e5b83d80822767698dfc0fc541be to your computer and use it in GitHub Desktop.
Save ChrisShank/5a49e5b83d80822767698dfc0fc541be to your computer and use it in GitHub Desktop.
freeCodeCamp: Build a Pomodoro Clock
<div class="water-container">
<svg class="waves" id="wave1" x="0px" y="0px" width="4000px" height="100px">
<rect x="0" y="0" width="4000" height="100" style="fill: none; stroke: none;"/>
<path fill="#FACA87" d="M3979.598,33c-36.77-12.655-119.326-21.479-215.27-21.479c-95.965,0-178.526,8.824-215.297,21.479h-43.754 c-31.063-9.575-89.989-16.045-157.61-16.045c-67.636,0-126.568,6.47-157.632,16.045h-6.848 c-40.914-12.655-132.776-21.479-239.537-21.479c-106.783,0-198.655,8.824-239.57,21.479h-11.395 c-64.555-10.638-183.124-17.772-318.715-17.772c-135.623,0-254.204,7.134-318.762,17.772h-29.32 c-60.742-12.627-196.83-21.427-354.954-21.427c-158.161,0-294.257,8.8-355.003,21.427h-19.847 c-49.024-12.655-159.1-21.479-287.023-21.479c-119.1,0-222.722,7.645-276.031,18.908c-37.599-11.263-110.684-18.908-194.674-18.908 c-75.893,0-142.867,6.24-182.824,15.749c-34.393-9.509-92.037-15.749-157.348-15.749c-77.688,0-144.527,8.824-174.294,21.479H7v60 h3993V33H3979.598z"/>
</svg>
<svg class="waves" id="wave2" x="0px" y="0px" width="4000px" height="100px">
<rect x="0" y="0" width="4000" height="100" style="fill: none; stroke: none;"/>
<path fill="#FACA87" d="M27.402,33c36.77-12.655,119.326-21.479,215.27-21.479c95.965,0,178.526,8.824,215.297,21.479h43.754 c31.063-9.575,89.989-16.045,157.61-16.045c67.636,0,126.568,6.47,157.632,16.045h6.848 c40.914-12.655,132.776-21.479,239.537-21.479c106.783,0,198.655,8.824,239.57,21.479h11.395 c64.555-10.638,183.124-17.772,318.715-17.772c135.623,0,254.204,7.134,318.762,17.772h29.32 c60.742-12.627,196.829-21.427,354.954-21.427c158.161,0,294.257,8.8,355.003,21.427h19.847 c49.023-12.655,159.1-21.479,287.023-21.479c119.1,0,222.722,7.645,276.031,18.908c37.599-11.263,110.684-18.908,194.674-18.908 c75.893,0,142.866,6.24,182.823,15.749c34.393-9.509,92.037-15.749,157.348-15.749c77.688,0,144.527,8.824,174.294,21.479H4000v60H7 V33H27.402z"/>
</svg>
<svg class="waves" id="wave3" x="0px" y="0px" width="4000px" height="100px">
<rect x="0" y="0" width="4000" height="100" style="fill: none; stroke: none;"/>
<path fill="#FACA87" d="M27.402,33c36.77-12.655,119.326-21.479,215.27-21.479c95.965,0,178.526,8.824,215.297,21.479h43.754 c31.063-9.575,89.989-16.045,157.61-16.045c67.636,0,126.568,6.47,157.632,16.045h6.848 c40.914-12.655,132.776-21.479,239.537-21.479c106.783,0,198.655,8.824,239.57,21.479h11.395 c64.555-10.638,183.124-17.772,318.715-17.772c135.623,0,254.204,7.134,318.762,17.772h29.32 c60.742-12.627,196.829-21.427,354.954-21.427c158.161,0,294.257,8.8,355.003,21.427h19.847 c49.023-12.655,159.1-21.479,287.023-21.479c119.1,0,222.722,7.645,276.031,18.908c37.599-11.263,110.684-18.908,194.674-18.908 c75.893,0,142.866,6.24,182.823,15.749c34.393-9.509,92.037-15.749,157.348-15.749c77.688,0,144.527,8.824,174.294,21.479H4000v60H7 V33H27.402z"/>
</svg>
<div class="water-bg"></div>
</div>
<h1>Pomodoro Timer</h1>
<div class="break">
<h4 class="break-title">Break</h4>
<div class="btn btn-sm" id="break-subtract-btn">
<i class="fa fa-minus"></i>
</div>
<div class="break-time"><span class="break-min-display">5</span>:<span class="break-sec-display">00</span></div>
<div class="btn btn-sm" id="break-add-btn">
<i class="fa fa-plus"></i>
</div>
</div>
<div class="btn btn-md" id="subtract-btn">
<i class="fa fa-minus"></i>
</div>
<div class="timer-display"><span class="min-display">25</span>:<span class="sec-display">00</span></div>
<div class="btn btn-md" id="add-btn">
<i class="fa fa-plus"></i>
</div>
<div class="btn btn-lg" id="pause-btn">
<i class="fa fa-play"></i>
</div>
<audio id="buzzer" preload="auto">
<source src="https://res.cloudinary.com/dafjb0lvm/video/upload/v1500648875/Alarm_Clock_Runs_Down.mp3"></source>
</audio>
<footer>
Programmed by <a href="https://codepen.io/shankc2323/" target="_blank">Chris Shank</a>. Design inspired by <a href="https://dribbble.com/shots/2492858-Liquid-Pomodoro-Timer" target="_blank">Dmitry Kurash</a>.
</footer>
var breakTime = false,
breakTranslateY,
breakMinDisplay = $(".break-min-display"),
breakSec,
breakSecDisplay = $(".break-sec-display"),
breakStartMin = 5,
countdownTimer,
currTranslateY = 0,
minDisplay = $(".min-display"),
pauseBtn = $("#pause-btn"),
pauseBtnIcon = $("#pause-btn i"),
sec,
secDisplay = $(".sec-display"),
startMin = 25,
translateY,
waterContainer = $(".water-container");
$(window).keypress(function(event) {
if(event.which === 32) {
pauseBtn.click();
}
});
pauseBtn.click(function() {
sec = parseInt(secDisplay.text()) + (60 * parseInt(minDisplay.text())) - 1,
breakSec = parseInt(breakSecDisplay.text()) + (60 * parseInt(breakMinDisplay.text())) - 1;
translateY = 97 / (startMin * 60);
breakTranslateY = 97 / (breakStartMin * 60);
if (pauseBtnIcon.hasClass("fa-play")) {
pauseBtnIcon.removeClass("fa-play");
pauseBtn.css({"text-indent": "0"});
pauseBtnIcon.addClass("fa-pause");
$(".break").animate({opacity: ".5"}, 750);
$(".btn-sm, .btn-md").fadeOut(1000);
if (breakTime) {
countdownTimer = setInterval('secPassedBreak()', 1000);
}
else {
countdownTimer = setInterval('secPassed()', 1000);
}
}
else {
clearInterval(countdownTimer);
pauseBtnIcon.removeClass("fa-pause");
pauseBtn.css({"text-indent": "4px"});
pauseBtnIcon.addClass("fa-play");
$(".timer-display, .break").animate({opacity: "1"}, 750);
$(".btn-sm, .btn-md").fadeIn(750);
}
});
function secPassed() {
var min = Math.round((sec - 30) / 60),
remainingSec = sec % 60;
if (remainingSec < 10) {
remainingSec = "0" + remainingSec;
}
if (sec <= 0) {
clearInterval(countdownTimer);
$("#buzzer")[0].play();
resetTimers();
$(".timer-display").animate({opacity: ".7"}, 750)
breakTime = true;
sec = (startMin * 60) - 1;
setTimeout(function() {
minDisplay.text(startMin);
alert("Time for a break!");
countdownTimer = setInterval('secPassedBreak()', 1000);
}, 2500);
}
else {
currTranslateY += translateY;
waterContainer.css({transform: "translateY(" + currTranslateY.toFixed(4) + "%)"});
minDisplay.text(min);
secDisplay.text(remainingSec);
sec--;
}
}
function secPassedBreak() {
var min = Math.round((breakSec - 30)/60),
remainingSec = breakSec % 60;
if (remainingSec < 10) {
remainingSec = "0" + remainingSec;
}
if (breakSec <= 0) {
clearInterval(countdownTimer);
$("#buzzer")[0].play();
resetTimers();
$(".break").animate({opacity: ".7"}, 750)
breakSec = (breakStartMin * 60) - 1;
setTimeout(function() {
breakMinDisplay.text(breakStartMin);
alert("Time to get back to work!");
countdownTimer = setInterval('secPassed()', 1000);
}, 2500);
}
else {
currTranslateY += breakTranslateY;
waterContainer.css({transform: "translateY(" + currTranslateY.toFixed(4) + "%)"});
breakMinDisplay.text(min);
breakSecDisplay.text(remainingSec);
breakSec--;
}
}
function resetTimers() {
$(".timer-display, .break").animate({opacity: "1"})
breakTime = false;
secDisplay.text("00");
breakSecDisplay.text("00");
if (currTranslateY > 0) {
currTranslateY = 0;
waterContainer.css({transform: "translateY(0)"});
}
}
$(".btn-sm").click(function() {
minDisplay.text(startMin);
resetTimers();
});
$(".btn-md").click(function() {
breakMinDisplay.text(breakStartMin);
resetTimers();
});
$("#break-subtract-btn").click(function() {
if (breakStartMin > 1) {
breakStartMin -= 1;
breakMinDisplay.text(breakStartMin);
}
});
$("#break-add-btn").click(function() {
if (breakStartMin < 60) {
breakStartMin += 1;
breakMinDisplay.text(breakStartMin);
}
});
$("#subtract-btn").click(function() {
if (startMin > 1) {
startMin -= 1;
minDisplay.text(startMin);
}
});
$("#add-btn").click(function() {
if (startMin < 60) {
startMin += 1;
minDisplay.text(startMin);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
body {
background: #FF732F;
color: white;
font-family: 'Dosis', sans-serif;
margin: 0;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
}
.water-container {
position: absolute;
bottom: 0;
height: 102%;
overflow: hidden;
width: 100%;
transform: translateY(0);
transition: transform .6s;
}
.waves {
position: absolute;
}
#wave1 {
animation: shake1 20s infinite;
animation-timing-function: linear;
margin-left: -200px;
opacity: 0.8;
top: 15px;
}
#wave2 {
animation: shake2 25s infinite;
animation-timing-function: linear;
opacity: 0.65;
margin-left: -2000px;
top: 5px;
}
#wave3 {
animation: shake1 23s infinite;
animation-timing-function: linear;
margin-left: -200px;
opacity: 0.5;
}
.water-bg {
background: linear-gradient(#FACA87, #FFC677 5%, #FEA462 60%);
height: 100%;
position: relative;
top: 85px;
}
h1 {
font-size: 45px;
margin: 0;
position: relative;
top: 10px;
text-align: center;
width: 100%;
}
.break {
border: white solid 2px;
border-radius: 5px;
font-size: 30px;
height: 95px;
position: absolute;
top: 17%;
left: calc(50% - 100px);
margin: 0;
text-align: center;
width: 200px;
}
.break-title {
margin: 5px 0 5px;
}
.break-time {
display: inline-block;
margin: 0;
user-select: none;
width: 70px;
}
.btn {
border: white solid 2px;
border-radius: 50%;
cursor: pointer;
margin: 0;
text-align: center;
transition: background-color .25s ease-in-out, color .25s ease-in-out, transform .08s ease-in-out;
user-select: none;
z-index: 4;
}
.btn:active {
transform: scale(.95);
}
.btn-sm {
display: inline-block;
font-size: 17px;
height: 30px;
line-height: 30px;
position: relative;
bottom: 4px;
text-align: center;
width: 30px;
}
.btn-md {
font-size: 23px;
height: 50px;
line-height: 50px;
position: absolute;
top: calc(50% - 25px);
width: 50px;
}
.btn-lg {
font-size: 40px;
height: 75px;
line-height: 75px;
position: absolute;
top: 65%;
left: calc(50% - 37.5px);
text-indent: 4px;
width: 75px;
}
.timer-display {
font-size: 90px;
height: 100px;
position: absolute;
top: calc(50% - 60px);
left: calc(50% - 125px);
text-align: center;
transition: all .3s ease-in-out;
user-select: none;
width: 250px;
z-index: 3;
}
#subtract-btn {
left: 2%;
}
#add-btn {
right: 2%;
}
footer{
color: white;
font-size: 15px;
position: fixed;
bottom: 0;
text-align: center;
user-select: none;
width: 100%;
}
@media screen and (min-width: 400px) {
.btn:hover {
background-color: white;
color: #FF732F;
}
#subtract-btn {
right: calc(50% + 142px);
left: auto;
}
#add-btn {
right: auto;
left: calc(50% + 142px);
}
footer {
font-size: 20px;
}
}
@media screen and (max-height: 400px) {
.break {
top: 5%;
left: 2%;
}
.btn-lg {
right: 2%;
top: 5%;
left: auto
}
}
@keyframes shake1 {
0% {
transform: translateX(0px);
}
50% {
transform: translateX(-1000px);
}
100% {
transform: translateX(0px);
}
}
@keyframes shake2 {
0% {
transform: translateX(0px);
}
50% {
transform: translateX(2000px);
}
100% {
transform: translateX(0px);
}
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment