Created a simple pomodoro timer with customizable session and break lengths for FreeCodeCamp.com zipline.
Forked from Geoff Storbeck's Pen Pomodoro Timer.
A Pen by Razafindrakoto on CodePen.
main(ng-app='PomodoroApp' ng-controller='MainCtrl') | |
header | |
.session | |
.breakCtrl | |
p break length | |
button(ng-click='breakLengthChange(-1)').minus - | |
span.time {{breakLength}} | |
button(ng-click='breakLengthChange(1)').plus + | |
.sessionCtrl | |
p session length | |
button(ng-click='sessionLengthChange(-1)').minus - | |
span.time {{sessionLength}} | |
button(ng-click='sessionLengthChange(1)').plus + | |
section(ng-click='toggleTimer()') | |
.timer | |
p.title {{sessionName}} | |
p {{timeLeft}} | |
span.fill(ng-style="{'height':fillHeight, 'background':fillColor }") | |
Created a simple pomodoro timer with customizable session and break lengths for FreeCodeCamp.com zipline.
Forked from Geoff Storbeck's Pen Pomodoro Timer.
A Pen by Razafindrakoto on CodePen.
var app = angular.module('PomodoroApp', []); | |
app.controller('MainCtrl', function($scope, $interval) { | |
$scope.breakLength = 5; | |
$scope.sessionLength = 25; | |
$scope.timeLeft = $scope.sessionLength; | |
$scope.fillHeight = '0%'; | |
$scope.sessionName = 'Session'; | |
$scope.currentTotal; | |
var runTimer = false; | |
var secs = 60 * $scope.timeLeft; | |
$scope.originalTime = $scope.sessionLength; | |
function secondsToHms(d) { | |
d = Number(d); | |
var h = Math.floor(d / 3600); | |
var m = Math.floor(d % 3600 / 60); | |
var s = Math.floor(d % 3600 % 60); | |
return ( | |
(h > 0 ? h + ":" + (m < 10 ? "0" : "") : "") + m + ":" + (s < 10 ? "0" : "") + s | |
); | |
} | |
// Change default session length | |
$scope.sessionLengthChange = function(time) { | |
if (!runTimer){ | |
if ($scope.sessionName === 'Session') { | |
$scope.sessionLength += time; | |
if ($scope.sessionLength < 1) { | |
$scope.sessionLength = 1; | |
} | |
$scope.timeLeft = $scope.sessionLength; | |
$scope.originalTime = $scope.sessionLength; | |
secs = 60 * $scope.sessionLength; | |
} | |
} | |
} | |
// Change default break length | |
$scope.breakLengthChange = function(time) { | |
if (!runTimer){ | |
$scope.breakLength += time; | |
if ($scope.breakLength < 1) { | |
$scope.breakLength = 1; | |
} | |
if ($scope.sessionName === 'Break!') { | |
$scope.timeLeft = $scope.breakLength; | |
$scope.originalTime = $scope.breakLength; | |
secs = 60 * $scope.breakLength; | |
} | |
} | |
} | |
$scope.toggleTimer = function() { | |
if (!runTimer) { | |
if ($scope.currentName === 'Sesson') { | |
$scope.currentLength = $scope.sessionLength; | |
} else { | |
$scope.currentLength = $scope.breakLength; | |
} | |
updateTimer(); | |
runTimer = $interval(updateTimer, 1000); | |
} else { | |
$interval.cancel(runTimer); | |
runTimer = false; | |
} | |
} | |
function updateTimer() { | |
secs -= 1; | |
if (secs < 0) { | |
// countdown is finished | |
// Play audio | |
var wav = 'http://www.oringz.com/oringz-uploads/sounds-917-communication-channel.mp3'; | |
var audio = new Audio(wav); | |
audio.play(); | |
// toggle break and session | |
$scope.fillColor = '#333333'; | |
if ($scope.sessionName === 'Break!') { | |
$scope.sessionName = 'Session'; | |
$scope.currentLength = $scope.sessionLength; | |
$scope.timeLeft = 60 * $scope.sessionLength; | |
$scope.originalTime = $scope.sessionLength; | |
secs = 60 * $scope.sessionLength; | |
} else { | |
$scope.sessionName = 'Break!'; | |
$scope.currentLength = $scope.breakLength; | |
$scope.timeLeft = 60 * $scope.breakLength; | |
$scope.originalTime = $scope.breakLength; | |
secs = 60 * $scope.breakLength; | |
} | |
} else { | |
if ($scope.sessionName === 'Break!') { | |
$scope.fillColor = '#FF4444'; | |
} else { | |
$scope.fillColor = '#99CC00'; | |
} | |
$scope.timeLeft = secondsToHms(secs); | |
var denom = 60 * $scope.originalTime; | |
var perc = Math.abs((secs / denom) * 100 - 100); | |
$scope.fillHeight = perc + '%'; | |
} | |
} | |
}); |
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script> |
@import "bourbon"; | |
@import url(http://fonts.googleapis.com/css?family=Pacifico|Open+Sans:300); | |
// colors | |
$green: #99CC00; | |
$black: #333333; | |
$white: #fff; | |
// variables | |
$font: Open Sans, Arial; | |
* { | |
margin: 0; | |
font-family: $font; | |
} | |
html, body, main { | |
height: 100%; | |
overflow: hidden; | |
background-color: $black; | |
} | |
h1 { | |
display: block; | |
background-color: $black; | |
margin: 0 auto; | |
color: white; | |
text-align: center; | |
font-family: 'Pacifico'; | |
font-size: 5em; | |
} | |
header { | |
display: flex; | |
justify-content: center; | |
text-align: center; | |
margin: 0 auto; | |
color: $white; | |
text-transform: uppercase; | |
padding: 20px; | |
.session { | |
font-size: .8em; | |
display: flex; | |
.breakCtrl, .sessionCtrl { | |
display: inline; | |
padding-left: 30px; | |
padding-right: 30px; | |
} | |
.minus, .plus { | |
background-color: $black; | |
color: $white; | |
border: none; | |
cursor: pointer; | |
font-size: 2em; | |
outline: none; | |
} | |
.time { | |
font-size: 2.5em; | |
padding-left: 10px; | |
padding-right: 10px; | |
} | |
} | |
} | |
section { | |
background-color: $black; | |
height: 100%; | |
color: $white; | |
.title { | |
text-align: center; | |
line-height: 180px; | |
font-size: .8em; | |
} | |
.timer { | |
margin: 0 auto; | |
text-align: center; | |
width: 300px; | |
height: 300px; | |
font-size: 4em; | |
border: 2px solid $green; | |
border-radius: 50%; | |
cursor: pointer; | |
position: relative; | |
z-index: 20; | |
overflow: hidden; | |
&:before { | |
content: ''; | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
border-radius: 50%; | |
z-index: 2; | |
border: 4px solid $black; | |
} | |
} | |
.fill { | |
content: ''; | |
position: absolute; | |
background: $green; | |
bottom: 0; | |
right: 0; | |
left: 0; | |
z-index: -1; | |
} | |
} |