harunpehlivan
3/6/2018 - 10:51 PM

Pomodoro Clock

Pomodoro Clock

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
@import url(https://fonts.googleapis.com/css?family=Maven+Pro:400,500,700);
body {    /* the  !important necessary to keep Bootstrap fonts from overriding Google fonts */
    font-family: 'Maven Pro', sans-serif !important;
    font-weight: 400 !important;
    font-size: 2em !important;
    height: 100%;
    background: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/wall_prints.jpg');
    background-size: auto;
    position: relative;
}

#main_container {
    width: auto;
    height: auto;
    padding: 0;
    margin: 0;
  }

#container-fluid {
    padding: 0;
    margin: 0;
}

.text h1 {
    font-size: 2.2em !important;
    margin-top: 40px;
    text-align: center;
    color: #0A342B;
    font-weight: 500 !important;
    text-shadow: 1px 1px 1px #000, 3px 3px 5px blue;
}


.text h3  {
    text-align: center;
    font-size: 1.1em !important;
    color: #89633d;
    margin-top: 0;
}

.text h3 a:link {
    color: #b54103;
    text-decoration: none;
}

.text h3 a:visited {
    color: #b54103;
    text-decoration: none;
}
.text h3 a:hover {
    color: #4a9ca5;
    text-decoration: none;
}

.text h3 a:active {
    color: #dd8023;
    text-decoration: none;
}

#clock_container {
    display: inline-block;
    width: 100%;
    margin-top: 40px;
    margin-left: 4px;
}

#liveclock {
    margin: 0 auto;
}

#work_length {
    text-align: center;
    margin: auto;
    color: #0A342B;
    padding-top: 96px;
    font-size: 0.9em !important;
    font-weight: bold;
}

#display_work_timer {
    color: #ff4500;
}

#display_play_timer {
    color: #0000ff;
}

#break_length {
    text-align: center;
    margin: auto;
    color: #0A342B;
    padding-top: 96px;
    font-size: 0.9em !important;
    font-weight: bold;
}

.bold {
    font-size: 1.0em !important;
    color: #0A342B;
    text-shadow: 1px 1px 2px #11342b;
}

#controls {
    border-radius: 6px;
    background-color:rgba(0, 0, 0, 0.1);
    text-align: center;
    margin: 20px auto;
    width: 260px;
    border: solid 1px darkseagreen;
}

#controls #ctrl-play.btn:hover {
    border: solid 1px #ff5000;
}

#controls #ctrl-play.btn:active {
    border: solid 1px red;
}

#controls #ctrl-pause.btn:hover {
    border: solid 1px #ff5000;
}

#controls #ctrl-pause.btn:active {
    border: solid 1px red;
}

#controls #ctrl-stop.btn:hover {
    border: solid 1px #ff5000;
}

#controls #ctrl-stop.btn:active {
    border: solid 1px red;
}

#controls #ctrl-repeat.btn:hover {
    border: solid 1px #ff5000;
}

#controls #ctrl-repeat.btn:active {
    border: solid 1px red;
}

#controls #ctrl-about.btn:hover {
    border: solid 1px #ff5000;
}

#controls #ctrl-about.btn:active {
    border: solid 1px red;
}

.pad {
    margin: 0 auto;
    height: 200px;
}

@media only screen and (max-width : 1200px) {
    #break_length {
        padding-left: 40px;
    }
}

@media only screen and (max-width : 991px) {
    #break_length {
        padding-top: 0;
        padding-left: 16px;
    }

    #work_length {
        padding-top: 0;
    }
}

/** CSS for Clock - modified for FCC Pomodoro Clock use **/

.outer_face {
    position: relative;
    width: 300px;                   /* width of clock */
    height: 300px;                  /* height of clock */
    border-radius: 40px;            /* clock round corner radius */
    background: #512d17;
    box-shadow: inset 0 0 16px #8E664D;
    border: 3px solid #ffa100;      /* thickness of outer border */
}

.outer_face::before, .outer_face::after, .outer_face .marker {      /* time markers style */
    content: "";
    position: absolute;
    width: 6px;                     /* width of 12-6 and 3-9 markers */
    height: 100%;
    background: black;
    z-index: 0;
    left: 50%;
    margin-left: -3px;              /* set this value of 1/2 marker width */
    top: 0;
}

.outer_face::after {
    -moz-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
}

.outer_face .marker {
    background: #9e5e1e;
    width: 4px;                     /* width of all other markers */
    margin-left: -2px;              /* set this value of 1/2 marker width */
}

.outer_face .marker.oneseven {
    -moz-transform: rotate(30deg);
    -ms-transform: rotate(30deg);
    -webkit-transform: rotate(30deg);
    transform: rotate(30deg);
}

.outer_face .marker.twoeight {
    -moz-transform: rotate(60deg);
    -ms-transform: rotate(60deg);
    -webkit-transform: rotate(60deg);
    transform: rotate(60deg);
}

.outer_face .marker.fourten {
    -moz-transform: rotate(120deg);
    -ms-transform: rotate(120deg);
    -webkit-transform: rotate(120deg);
    transform: rotate(120deg);
}

.outer_face .marker.fiveeleven {
    -moz-transform: rotate(150deg);
    -ms-transform: rotate(150deg);
    -webkit-transform: rotate(150deg);
    transform: rotate(150deg);
}

.inner_face {
    position: relative;
    width: 88%;
    height: 88%;
    background: #512d17;
    -moz-border-radius: 1000px;
    -webkit-border-radius: 1000px;
    border-radius: 1000px;
    z-index: 1000;
    left: 6%;                       /* set this value of 1/2 width value*/
    top: 6%;                        /* set this value of 1/2 height value*/
}

.inner_face:before {
    /* clock center circle small */
    content: "";
    width: 40px;                    /* width of inner circle */
    height: 40px;                   /* height of inner circle */
    border-radius: 18px;
    margin-left: -20px;             /* set this value of 1/2 width value*/
    margin-top: -20px;              /* set this value of 1/2 height value*/
    background: url(http://images.ticiz.com/2603690_w0_h120_hnn1i...bv9ettdv9dsbugw0py.png);
    position: absolute;
    top: 50%;
    left: 50%;
}

.inner_face:after {
    content: "FreeCodeCamp";
    position: absolute;
    width: 100%;
    font: normal 0.6em Arial !important;
    color: gray;
    text-align: center;
    top: 84%;
    z-index: 0;
}

.hand, .hand.hour {
    position: absolute;
    width: 3px;                     /* width of hour hand */
    height: 31%;                    /* height of hour hand */
    top: 20%;                       /* set top to 50% - height */
    left: 50%;
    margin-left: -1.5px;            /* set this value to 1/2 width */
    background: black;
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    -moz-transform-origin: bottom;
    -ms-transform-origin: bottom;
    -webkit-transform-origin: bottom;
    transform-origin: bottom;
    z-index: -1;
    -moz-box-shadow: 0 0 1px #512d17;
    -webkit-box-shadow: 0 0 1px #512d17;
    box-shadow: 0 0 1px #512d17;
}

.hand.minute {
    height: 45%;                    /* height of min hand */
    top: 5%;                        /* set top to 50% - height */
    width: 3px;                     /* width of min hand */
    margin-left: -1.5px;            /* set this value to 1/2 width */
}

.hand.second {
    height: 50%;                    /* height of sec hand */
    width: 2px;                     /* width of sec hand */
    margin-left: -1px;              /* set this value to 1/2 width */
    top: 0;
    background: red;
}

.hand.work {
    height: 16%;                    /* height of work hand */
    width: 2px;                     /* width of work hand */
    margin-left: -1px;              /* set this value to 1/2 width */
    top: 90px;
    background: #ff4500;
}

.hand.break {
    height: 16%;                    /* height of break hand */
    width: 2px;                     /* width of break hand */
    margin-left: -1px;              /* set this value to 1/2 width */
    top: 90px;
    background: #0000ff;
}
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
/**
 *  Created by Rick Stewart on 11/20/2015.
 */


/* 'exported' statement tells JsHint to ignore 'function never used' warning as they are called externally */
/* exported plusWorkTime */
/* exported minusWorkTime */
/* exported plusBreakTime */
/* exported minusBreakTime */
/* exported playAlarm */
/* exported start */
/* exported stop */
/* exported reset */
/* exported popOpenInfoWindow */

'use strict';                                      // tells browsers to use strict - a best practice

var workLength = 25;                               // default of 25 minutes for a pomodoro
var breakLength = 5;                               // default of 5 minutes for a break
var $hands = $('#liveclock').find('div.hand');     // get reference
var freezeHands = false;                           // if true pomodoro hands (work, break ) stop advancing
var workAsDegree = 0;
var breakAsDegree = 0;
var frozenWorkAsDegree = 0;
var frozenBreakAsDegree = 0;
var targetDisplayWorkLength = document.getElementById('display_work_timer');   // store HTML page location work length
var targetDisplayBreakLength = document.getElementById('display_play_timer');  // store HTML page location break length
var alarmNotTriggeredFlag =  true;                    // 'true' if alarm was not yet triggered
var timerRunning = false;                             // 'true' when timer running a pomodoro
var infoWindow;

targetDisplayWorkLength.innerHTML = workLength;    // set initial work length
targetDisplayBreakLength.innerHTML = breakLength;  // set initial break length

var plusWorkTime = function() {                          // increment work time value
    if(workLength <= 58) {
        workLength += 1;
        targetDisplayWorkLength.innerHTML = workLength;
    }
};

var minusWorkTime = function() {                         // decrement work length value
    if(workLength >= 2) {
        workLength -= 1;
        targetDisplayWorkLength.innerHTML = workLength;
    }
};

var plusBreakTime = function() {                          // increment break time value
    if(breakLength <= 58) {
        breakLength += 1;
        targetDisplayBreakLength.innerHTML = breakLength;
    }
};

var minusBreakTime = function() {                        // decrement break length value
    if(breakLength >= 2) {
        breakLength -= 1;
        targetDisplayBreakLength.innerHTML = breakLength;
    }
};

var playAlarm = function() {
    var audioElement = document.createElement('audio');
    audioElement.setAttribute('src', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/tinsha.mp3');
    audioElement.play();
};

/***********************************************
 * FreeCodeCamp Pomodoro Clock based on:
 *
 * CSS3 Analog Clock- by JavaScript Kit (www.javascriptkit.com)
 * http://www.javascriptkit.com/script/script2/css3analogclock.shtml
 ***********************************************/

var setFreezeHands = function(bool) {
    freezeHands = bool;
};

var setRunning = function(bool) {
    timerRunning = bool;
};

var setAlarmTriggered = function(bool) {
    alarmNotTriggeredFlag = bool;
};

var setTimeAtStart = function() {                  // record start time for pomodoro
    var currentDate = new Date();
    frozenWorkAsDegree = (workLength / 60 * 360) + (currentDate.getMinutes() / 60 * 360);
    frozenBreakAsDegree = frozenWorkAsDegree + (breakLength / 60 * 360);
};

/*  Control Panel buttons  */
var start = function() {
    setTimeAtStart();
    setRunning(true);
    setFreezeHands(true);

};

var stop = function() {
    setFreezeHands(false);
    setRunning(false);
};

var reset = function() {
    workLength = 25;                               // reset to default values
    breakLength = 5;
    targetDisplayWorkLength.innerHTML = workLength;    // set  work length
    targetDisplayBreakLength.innerHTML = breakLength;  // set break length
    setFreezeHands(false);
    setRunning(false);
};

var popOpenInfoWindow = function() {               // opens information window
    var leftValue = (screen.width/2)-(300/2);      // centers window on viewport
    var topValue = (screen.height/2)-(400/2);
    infoWindow = window.open('','infoWindow','height=400px,width=300px,left='+leftValue+',top='+topValue+',menubar=no,resizable=no,status=yes,titlebar=no,location=no,scrollbars=yes');
    infoWindow.document.write('<html><head><title>Helpful Information</title>');
    infoWindow.document.write('<link rel="stylesheet" href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/popupStyle.css">');
    infoWindow.document.write('</head><body>');
    infoWindow.document.write('<h2>User Guide</h2>');
    infoWindow.document.write('<p><a href="https://en.wikipedia.org/wiki/Pomodoro_Technique" target="_blank">Wiki article describing Pomodoro</a></p>');
    infoWindow.document.write('<h4>\"Play\"</h4>');
    infoWindow.document.write('<p>Starts a countdown equal to the number of minutes set by the Work Duration. A chime will sound when this countdown completes.</p>');
    infoWindow.document.write('<p>When a Work Period ends a second countdown begins, this time equal to the set Break Time. Again a chime will sound when this countdown completes.</p>');
    infoWindow.document.write('<p>This cycle repeats indefinitely until either the Stop or Reset button is pushed.</p>');
    infoWindow.document.write('<p>The short orange hand on the clock face indicates Work Time remaining. When the minute hand reaches the orange hand, work time is up.</p>');
    infoWindow.document.write('<p>In the same fashion the short blue colored hand indicates Break Time remaining.</p>');
    infoWindow.document.write('<h4>Stop</h4>');
    infoWindow.document.write('<p>Pushing Stop ends the countdown, and leaves Work Duration and Break Duration unchanged.</p>');
    infoWindow.document.write('<h4>Reset</h4>');
    infoWindow.document.write('<p>Pushing Reset ends the countdown, and returns Work Duration and Break Duration to default values.</p>');
    infoWindow.document.write('<br/>');
    infoWindow.document.write('<p><a href="javascript:self.close()">Close</a> this popup.</p>');
    infoWindow.document.write('<br/>');
    infoWindow.document.write('</body></html>');
    infoWindow.document.close();
};

window.requestAnimationFrame = window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function (f) {
        setTimeout(f, 60);
    };

var updateClock = function () {
    var theDate = new Date();
    var hourAsDegree = ( theDate.getHours() + theDate.getMinutes() / 60 ) / 12 * 360;
    var minuteAsDegree = theDate.getMinutes() / 60 * 360;
    var secondAsDegree = ( theDate.getSeconds() + theDate.getMilliseconds() / 1000 ) / 60 * 360;
    $hands.filter('.hour').css({transform: 'rotate(' + hourAsDegree + 'deg)'});
    $hands.filter('.minute').css({transform: 'rotate(' + minuteAsDegree + 'deg)'});
    $hands.filter('.second').css({transform: 'rotate(' + secondAsDegree + 'deg)'});
    if (freezeHands) {
        /** if freezeHands == true, hands 'work' and 'break' do not advance **/
        $hands.filter('.work').css({transform: 'rotate(' + frozenWorkAsDegree + 'deg)'});
        /** pomodoro work hand **/
        $hands.filter('.break').css({transform: 'rotate(' + frozenBreakAsDegree + 'deg)'});
        /** pomodoro break hand **/
    }
    else {
        workAsDegree = minuteAsDegree + (workLength / 60 * 360);
        breakAsDegree = workAsDegree + (breakLength / 60 * 360);
        $hands.filter('.work').css({transform: 'rotate(' + workAsDegree + 'deg)'});
        $hands.filter('.break').css({transform: 'rotate(' + breakAsDegree + 'deg)'});
    }
    if(((frozenWorkAsDegree % 360) === (minuteAsDegree % 360)) && alarmNotTriggeredFlag && timerRunning) {  // work time expired?
         playAlarm();
         setAlarmTriggered(false);
    }
    if(((frozenBreakAsDegree % 360) === (minuteAsDegree % 360)) && !alarmNotTriggeredFlag && timerRunning) {  // break time expired?
        playAlarm();
        setAlarmTriggered(true);
        setFreezeHands(false);
        start();
    }
    requestAnimationFrame(updateClock);
};

$(window).load (function () {                      // start animation running
    requestAnimationFrame(updateClock);
});

Pomodoro Clock

FreeCodeCamp Zipline to design and implement a Pomodoro Clock.

http://www.freecodecamp.com/challenges/zipline-build-a-pomodoro-clock

A Pen by HARUN PEHLİVAN on CodePen.

License.

<!-- <!DOCTYPE html> -->
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Pomodoro Clock</title>
  <!-- my stylesheet comes after Bootstrap css so I can override some of it  -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/bootstrap.min.css">
  <link href='https://fonts.googleapis.com/css?family=Maven+Pro:400,500,700' rel='stylesheet' type='text/css'>
  <!-- Javascript library adds needed browser vendor prefixes  -->
  <!-- to automatically fix compatibility issues in older browsers -->
  <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/prefixfree_1.0.7.min.js">
  <link rel="stylesheet" href="css/main.css">
  </script>
</head>
<body>

<div id="main_container">

  <div class="container">

    <div class="title row">
      <span class="col-xs-1 col-sm-3 col-md-3 col-lg-3"></span>

      <div class="text col-xs-10 col-sm-6 col-md-6 col-lg-6">
        <h1>Pomodoro Clock</h1>

        <h3>
          <a href="https://www.freecodecamp.org/harunpehlivan" target="_blank">
            a FreeCodeCamp Zipline</a>
        </h3>
      </div>
      <span class="col-xs-1 col-sm-3 col-md-3 col-lg-3"></span>
    </div>
  </div>


  <div class="container">

    <div id="clock_container" class="row button-container">

      <div id="clock_span" class="col-xs-12 col-sm-12 col-md-4 col-lg-4 col-md-push-4">
        <div id="liveclock" class="outer_face ">
          <div class="marker oneseven"></div>
          <div class="marker twoeight"></div>
          <div class="marker fourten"></div>
          <div class="marker fiveeleven"></div>
          <div class="inner_face">
            <div class="hand hour"></div>
            <div class="hand minute"></div>
            <div class="hand second"></div>
            <div id="work" class="hand work"></div>
            <div id="break" class="hand break"></div>
          </div>
        </div>

        <div id="controls" class="row button-container">
          <span id="ctrl-play" class="btn popup" title="Start your Pomodoro" onclick="start()"><img
              src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/PlayHS.png"></span>
          <span id="ctrl-stop" class="btn popup" title="Stop your Pomodoro" onclick="stop()"><img
              src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/StopHS.png"></span>
          <span id="ctrl-repeat" class="btn popup" title="Reset to Default" onclick="reset()"><img
              src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/RepeatHS.png"></span>
          <span id="ctrl-about" class="btn popup" title="Helpful Information" onclick="popOpenInfoWindow()"><img
              src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/Task-Inspector-Suggestion.png"></span>
        </div>
      </div>

      <div id="work_length" class="col-xs-12 col-sm-12 col-md-4 col-lg-4 col-md-pull-3">
        <p class="bold">Work Duration:</p>
        <span id="btn-work-left" class="btn glyphicon glyphicon-chevron-left" onclick="minusWorkTime()"></span>
        <span id="display_work_timer"></span>
        <span id="btn-work-right" class="btn glyphicon glyphicon-chevron-right" onclick="plusWorkTime()"></span>

        <p>minutes</p>
      </div>

      <div id="break_length" class="col-xs-12 col-sm-12 col-md-4 col-lg-4 col-md-pull-1">
        <p class="bold">Break Duration:</p>
        <span id="btn-break-left" class="btn glyphicon glyphicon-chevron-left" onclick="minusBreakTime()"></span>
        <span id="display_play_timer"></span>
        <span id="btn-break-right" class="btn glyphicon glyphicon-chevron-right" onclick="plusBreakTime()"></span>

        <p>minutes</p>
      </div>

    </div> <!-- clock_container -->
  </div> <!-- container-fluid -->
</div> <!-- main container -->

<!-- my javascript file comes after Bootstrap and JQuery js so I can override some of it -->
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/jquery-1.11.3.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/368633/bootstrap.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>