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; | |
| } | |
| } |