cssAudio - ActiveCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - Activehtmlicon-personicon-teamoctocatspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <html>
<head>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <link rel="stylesheet" href="css/style.css" />

  <title>Time Left</title>

</head>

<body>

  <div class="page-wrapper">

     <div id="center-container">
      <div id="ring"></div>
      <div id="ring-2"></div>
      <div id="main-clock-container">

        <svg id="main-clock" xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">

            <circle cx="250" cy="250" r="220" id="pie"/>

            <!--A rx ry x-axis-rotation large-arc-flag sweep-flag x y-->

            <path d="M250 250
            L 140 59
            A 220 220 0 0 1 470 250
            L 250 250
            "
            stroke="#eee" stroke-width="0"
            id="sleep-slice" class="slice" />

            <path d="M250 250
            L 441 360
            A 220 220 0 0 1 37 307
            L 250 250
            "
            stroke="#eee" stroke-width="0"
            id="work-slice" class="slice" />

            <line class="crosshairs" x1="30" y1="250" x2="470" y2="250" stroke-width="1"/>
            <line class="crosshairs" x1="250" y1="30" x2="250" y2="470" stroke-width="1"/>

            <line x1="250" y1="250" x2="413" y2="125" stroke="#aaa" stroke-width="2" stroke-linecap="round" id="hour-hand"/>
            <line x1="250" y1="250" x2="413" y2="125" stroke="#aaa" stroke-width="2" stroke-linecap="round" id="hour-hand-opposite"/>

            <line x1="250" y1="250" x2="413" y2="125" stroke="#333" stroke-width="1" stroke-linecap="round" id="second-hand"/>

            <line x1="250" y1="250" x2="413" y2="125" stroke="#333" stroke-width="1" stroke-linecap="round" id="second-hand-opposite"/>

            <circle cx="250" cy="250" r="5" id="second-hand-circle"/>

        </svg>

        <div class="tooltip main">
          <span class="tooltip-label main"></span>
          <span class="tooltip-data main"></span>
          <span class="tooltip-hrs main"></span>
        </div>

      </div>
    </div>

    <div id="mini-clock-container">

      <svg id="mini-clock" xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250">

        <circle cx="125" cy="125" r="125" id="mini-clock-face"/>

        <path d="M125 125
        L 125 0
        A 125 125 0 0 0 125 0
        L 125 125
        "
        stroke-width="1" id="mini-clock-slice" class="slice" />

      </svg>
      <div id="mini-clock-busy">xyz</div>
      <div class="tooltip mini">
        <span class="tooltip-label mini"></span>
        <span class="tooltip-data mini"></span>
        <span class="tooltip-hrs mini"></span>
      </div>

    </div>


    <div id="time-inputs-container">
      <label for="bedtime">Go to bed</label>
      <input type="text" id="bedtime" onclick="this.select();">
      <label for="waketime">Wake up</label>
      <input type="text" id="waketime" onclick="this.select();">

      <label for="go-to-work">Go to work</label>
      <input type="text" id="go-to-work" onclick="this.select();">
      <label for="come-home">Come home</label>
      <input type="text" id="come-home" onclick="this.select();">
    </div>

    <div id="free-time-container">
      <label for="free-time">Hours of free<br>time per day</label>
      <span id="free-time">Free time</span>
    </div>

    <div id="date-container">
      <span id="day-name">wednesday</span>
      <span id="day-number">08</span>
      <span id="month-name">april</span>
    </div>

    <div id="timer-container">
      <label for="timer-display" id="timer-label">Time until bedtime</label>
      <span id="timer-display">Timer</span>
    </div>

  </div>

</body>

</html>

            
          
!
            
              $hue: 205;
$hue-complement: ($hue + 180) % 360;

$page-bg-color: hsl($hue,40%,13%);
$pie-bg-color: hsl($hue,40%,11%);
// $pie-bg-color: $page-bg-color;
$num-color: hsla($hue,100%,80%,0.5);
$sleep-slice-color: hsl($hue,40%,30%);
$sleep-slice-color-hover: hsl($hue,40%,70%);
$work-slice-color: hsl($hue,40%,50%);
$work-slice-color-hover: hsl($hue,40%,70%);

$mini-clock-face-bg-color: hsl($hue,40%,11%);
$mini-clock-face-bg-color-hover: hsl($hue,40%,30%);
$mini-clock-slice-color: hsl($hue,40%,40%);
$mini-clock-slice-color-hover: hsl($hue,40%,60%);
$mini-clock-busy-font: 200 13px 'Helvetica Neue';
$mini-clock-busy-color: hsl($hue,40%,60%);

// global scss goes here
$page-background-color: hsl($hue,30%,7%);
$default-font-family: 'Helvetica Neue';
$default-text-color: hsl($hue,40%,70%);
$default-link-color: hsl($hue,70%,50%);
$default-font-size: 16px;
$default-line-height: 150%;

$label-color: hsla($hue,100%,80%,0.5);
$small-label-font: 200 10px 'Helvetica Neue';
$small-label-font-color: hsla($hue,70%,80%,0.4);

$timer-font: 100 60px 'Helvetica Neue';
$timer-color: hsla($hue,70%,80%,0.9);
$timer-font-size: 60px;
$timer-label-font: $small-label-font;
$timer-label-font-color: $small-label-font-color;
$free-time-label-font: 200 10px 'Helvetica Neue';
$free-time-font: $timer-font;
$free-time-color: hsla($hue,70%,80%,0.9);
$time-inputs-font: 300 20px 'Helvetica Neue';
$time-inputs-font-color: hsla($hue,70%,80%,0.6);
$time-inputs-focus-color: hsla($hue,70%,80%,0.9);
$time-inputs-background-color: hsla($hue,100%,0%,0.2);
$time-inputs-background-focus-color: hsla($hue,50%,0%,0.1);
$time-inputs-background-focus-border: 2px solid hsla($hue,90%,80%,0.7);
$time-inputs-background-focus-shadow: 0 0 5px 3px hsla($hue,90%,70%,0.5);
// $time-inputs-labels-font: 400 12px 'Helvetica Neue';
$time-inputs-labels-font: $small-label-font;
// $time-inputs-labels-font-color: hsla($hue,70%,80%,0.5);
$time-inputs-labels-font-color: $small-label-font-color;

$ring-color: hsla($hue,100%,80%,0.1);
$ring-border-top-color: hsla($hue,100%,80%,0.7);
$ring-2-color: hsla($hue,100%,80%,0.1);
$ring-2-border-top-color: hsla($hue,100%,80%,0.4);

$day-name-font: $small-label-font;
$day-name-color: $small-label-font-color;
$day-number-font: $timer-font;
$month-name-font: $small-label-font;

$tooltip-label-font: 200 10px 'Helvetica Neue';
$tooltip-label-color: #aaa;
$tooltip-data-font: 100 35px 'Helvetica Neue';
$tooltip-data-color: #eee;
$tooltip-hrs-font: 200 10px 'Helvetica Neue';
$tooltip-hrs-color: #aaa;
$tooltip-bg-color: hsla(0,0%,0%,0.6);

@mixin electric-border {
  border: 1px solid hsla($hue,100%,70%,0.2);
  border-radius: 20px;
}

html { height: 100%; overflow: hidden; }

body {
  background-color: $page-bg-color;
  font-family: $default-font-family;
  color: $default-text-color;
  height: 100%;
  line-height: $default-line-height;
  overflow: hidden;
}

h1, h2, h3, h4, h5, h6 {
  margin: 1em 0;
  color: $default-text-color;
  font-weight: bold;
}

h1 {
  font-size: $default-font-size * 2;
  margin-top: 0;
}

h2 {
  font-size: $default-font-size * 1.5;
}

p {
  margin: 1em 0;
}

p, ul, ol, blockquote, pre {
  line-height: $default-line-height;
  letter-spacing: 0.1px;
}

ul, ol {
  margin: 0;
}

strong {
  font-weight: bold;
}

em {
  font-style: italic;
}

a {
  color: $default-link-color;
  text-decoration: none;
  &:hover {
    text-decoration: underline;
  }
}

.page-wrapper {
  position: relative;
  padding: 50px;
  width: 930px;
  margin: 50px auto 0 auto;
}


svg {
  display: block;
  background: none;
}

#pie {
  fill: $pie-bg-color;
}

#sleep-slice {
  fill: $sleep-slice-color;
  transition: fill 0.3s ease;
}

#sleep-slice:hover {
  fill: $sleep-slice-color-hover;
}

#work-slice {
  fill: $work-slice-color;
  transition: fill 0.3s ease;
}

#work-slice:hover {
  fill: $work-slice-color-hover;
}

.number-label {
  fill: $num-color;
  font-family: 'Helvetica Neue';
  font-weight: 400;
  font-size: 13px;
}

.crosshairs {
  stroke: hsla($hue, 100%, 80%, 0.3);
  pointer-events: none;
}

#hour-hand,
#hour-hand-opposite {
  stroke: hsl($hue,50%,80%);
  stroke-width: 2;
  pointer-events: none;
}

#second-hand,
#second-hand-opposite {
  stroke: hsl($hue,50%,80%);
  pointer-events: none;
}

#second-hand-circle {
  fill: hsl($hue,50%,80%);
  pointer-events: none;
}

.tooltip {
  position: absolute;
  float: left;
  min-width: 80px;
  // height: 80px;
  top: 300px;
  left: 70px;
  padding: 7px 9px;
  z-index: 5;
  display: none;
  border-radius: 7px;
  background-color: $tooltip-bg-color;
  // box-shadow: 0 3px 3px #222;
  pointer-events: none;
  text-align: left;
  white-space:nowrap;
}

.tooltip-label {
  display: block;
  font: $tooltip-label-font;
  color: $tooltip-label-color;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.tooltip-data {
  font: $tooltip-data-font;
  color: $tooltip-data-color;
}

.tooltip-hrs {
  font: $tooltip-hrs-font;
  color: $tooltip-hrs-color;
  letter-spacing: 1px;
}

#mini-clock-container {
  display: none;
  position: absolute;
  top: 418px;
  right: 0;
}

#mini-clock {

}

#mini-clock-face {
  fill: $mini-clock-face-bg-color;
  transition: fill 0.3s ease;
  &:hover {
    fill: $mini-clock-face-bg-color-hover;
  }
}

#mini-clock-slice {
  fill: $mini-clock-slice-color;
  transition: fill 0.3s ease;
  &:hover {
    fill: $mini-clock-slice-color-hover;
  }
}

#mini-clock-busy {
  // position: absolute;
  // top: 125;
  // left: 125;
  margin: -130px auto 0 auto;
  width: 100px;
  text-align: center;
  font: $mini-clock-busy-font;
  color: $mini-clock-busy-color;
}


#center-container {
  // background-color: #222;
  width: 550px;
  height: 550px;
  display: block;
  position: relative;
  top: 0;
  margin: -25px auto 0 auto;
  // left: 25%;
}

#main-clock-container {
  position: relative;
  // background-color: hsla(0,0%,30%,0.3);
  text-align: center;
  width: 500px;
  height: 500px;
  margin: 0 auto 20px auto;
}


#timer-container {
  display: block;
  width: 300px;
  position: absolute;
  top: 560px;
  left: 50%;
  margin: 0 auto 0 -150px;
  font: $timer-label-font;
  text-align: center;
}

#timer-display {
  @include electric-border;
  font: $timer-font;
  color: $timer-color;
  width: 280px;
  display: block;
  line-height: 100%;
  margin: 0 auto;
  padding: 10px 0 12px 0;
  text-rendering: optimizeLegibility;
  transition: all 1s ease-in-out;
}

label[for="timer-display"] {
  color: $small-label-font-color;
  display: block;
  text-transform: uppercase;
  letter-spacing: 1px;
  // word-spacing: 1px;
  font: $timer-label-font;
  margin-bottom: 10px;
}


#free-time-container {
  display: block;
  position: absolute;
  right: 0;
  top: 140px;
  margin: 15px auto 0 auto;
  text-transform: uppercase;
  width: 150px;
  padding: 19px 0;
  text-align: center;
  @include electric-border;
}

label[for="free-time"] {
  font: $free-time-label-font;
  color: $small-label-font-color;
  display: block;
  text-transform: uppercase;
  letter-spacing: 1px;
  // word-spacing: 1px;
  margin-bottom: 2px;
}

#free-time {
  font: $free-time-font;
}


#time-inputs-container {
  position: absolute;
  width: 150px;
  // background-color: hsla(0,0%,100%,0.1);
  left: 0;
  top: 0;
  text-align: center;
  padding: 25px 0 15px 0;
  @include electric-border;
}

#bedtime,
#waketime,
#go-to-work,
#come-home,
label[for="bedtime"],
label[for="waketime"],
label[for="go-to-work"],
label[for="come-home"] {
  display: block;
  margin: 0 auto;
}

label[for="bedtime"],
label[for="waketime"],
label[for="go-to-work"],
label[for="come-home"] {
  text-transform: uppercase;
  font: $time-inputs-labels-font;
  color: $time-inputs-labels-font-color;
  letter-spacing: 1px;
}

#bedtime,
#waketime,
#go-to-work,
#come-home {
  outline: none;
  border: none;
  background-color: $time-inputs-background-color;
  border-radius: 10px;
  font: $time-inputs-font;
  width: 80px;
  height: 60px;
  text-align: center;
  color: $time-inputs-font-color;
  letter-spacing: 0.5px;
  margin-top: 5px;
  margin-bottom: 20px;
  transition: background-color 0.5s, border 0.5s, box-shadow 0.5s,
              color 0.5s;
  &:focus {
    background-color: $time-inputs-background-focus-color;
    border: $time-inputs-background-focus-border;
    box-shadow: $time-inputs-background-focus-shadow;
    color: $time-inputs-focus-color;
  }
  &::selection {
    background: hsla($hue,40%,60%,0.5);
  }
}


#date-container {
  position: absolute;
  top: 0px;
  right: 0;
  width: 150px;
  text-align: center;
  padding: 23px 0;
  @include electric-border;
}

#day-name {
  font: $day-name-font;
  color: $small-label-font-color;
  display: block;
  text-transform: uppercase;
  margin-bottom: 0;
  letter-spacing: 1px;
}

#day-number {
  display: block;
  font: $day-number-font;
  text-align: center;
  line-height: 100%;
}


#month-name {
  font: $month-name-font;
  color: $small-label-font-color;
  display: block;
  text-transform: uppercase;
  margin-bottom: 0;
  letter-spacing: 1px;
}



/* Animations */

@keyframes turn_clockwise {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
@-webkit-keyframes turn_clockwise {
    0% {
        -webkit-transform: rotate(0deg);
    }
    100% {
        -webkit-transform: rotate(360deg);
    }
}

@keyframes turn_counter_clockwise {
    0% {
        transform: rotate(360deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
@-webkit-keyframes turn_counter_clockwise {
    0% {
        -webkit-transform: rotate(360deg);
    }
    100% {
        -webkit-transform: rotate(0deg);
    }
}



#ring {
  box-sizing:border-box;
  -moz-box-sizing:border-box;
  -webkit-box-sizing:border-box;
  position: absolute;
  display: inline-block;
  border: 3px solid $ring-color;
  text-align: center;
  border-top-color: $ring-border-top-color;
  width: 530px;
  height: 530px;
  margin: 0 auto;
  left: 50%;
  margin-left: -265px;
  top: -15px;
  border-radius: 100%;
  animation: turn_clockwise 60s linear infinite;
  -webkit-animation: turn_clockwise 60s linear infinite;
}

#ring-2 {
  box-sizing:border-box;
  -moz-box-sizing:border-box;
  -webkit-box-sizing:border-box;
  position: absolute;
  display: inline-block;
  border: 2px dotted $ring-2-color;
  text-align: center;
  border-top-color: $ring-2-border-top-color;
  width: 550px;
  height: 550px;
  margin: 0 auto;
  left: 50%;
  margin-left: -275px;
  top: -25px;
  border-radius: 100%;
  animation: turn_counter_clockwise 30s linear infinite;
  -webkit-animation: turn_counter_clockwise 30s linear infinite;
}


            
          
!
            
              'use strict';

(function timeleft(){

  // getMonthName and getDayName
  // taken from http://javascript.about.com/library/bldatenames.htm
  Date.prototype.getMonthName = function() {
    var m = ['January','February','March','April','May','June','July',
    'August','September','October','November','December'];
    return m[this.getMonth()];
  }
  Date.prototype.getDayName = function() {
    var d = ['Sunday','Monday','Tuesday','Wednesday',
    'Thursday','Friday','Saturday'];
    return d[this.getDay()];
  }

  // check if integer (includes strings)
  function isInt(value) {
    return !isNaN(value) &&
           parseInt(Number(value)) == value &&
           !isNaN(parseInt(value, 10));
  }

  var schedule = {
    bedTime: 22,
    wakeTime: 6.5,
    goToWorkTime: 8,
    comeHomeTime: 17.5,
    totalBed: 0,
    totalWork: 0,
    freeTime: 0,
    isPreWork: false,
    isPreBed: false,
    isAtWork: false,
    isInBed: false,
    totalPreWorkFreeTime: 0,
    totalPreBedFreeTime: 0,
    totalHoursRemainingUntilNextThing: 0,
    bedTimeDate: new Date(),
    goToWorkDate: new Date(),
    wakeTimeDate: new Date(),
    comeHomeDate: new Date(),
  };

  var clock = {
    width: 440,
    height: 440,
    radius: 220,
    numDistFromEdge: 15,
    secondHandDistFromEdge: 5,
    secondHandLengthOfShortSide: 70,
    hourHandDistFromEdge: 40,
    hourHandLengthOfShortSide: 30,
    increment: 0.03,
    delay: 10,
    svg: document.getElementById('main-clock'),
    sleepSlice: document.getElementById('sleep-slice'),
    workSlice: document.getElementById('work-slice'),
    hourHand: document.getElementById('hour-hand'),
    hourHandShortSide: document.getElementById('hour-hand-opposite'),
    secondHand: document.getElementById('second-hand'),
    secondHandShortSide: document.getElementById('second-hand-opposite'),
  };

  clock.centerX = (clock.width / 2) + 30;
  clock.centerY = (clock.height / 2) + 30;

  var miniClock = {
    width: 250,
    height: 250,
    radius: 125,
    delay: 16,
    svg: document.getElementById('mini-clock'),
    slice: document.getElementById('mini-clock-slice'),
    busy: document.getElementById('mini-clock-busy'),
  };

  miniClock.centerX = miniClock.width / 2;
  miniClock.centerY = miniClock.height / 2;

  schedule.totalBed = measureTime(schedule.bedTime, schedule.wakeTime);
  schedule.totalWork = measureTime(schedule.goToWorkTime, schedule.comeHomeTime);

  var timer = {
    display: document.getElementById('timer-display'),
    label: document.getElementById('timer-label'),
  };

  var timeControls = {
    bedtimeInput: document.getElementById('bedtime'),
    waketimeInput: document.getElementById('waketime'),
    goToWorkInput: document.getElementById('go-to-work'),
    comeHomeInput: document.getElementById('come-home'),
  };

  var newBedTime = schedule.bedTime;
  var newWakeTime = schedule.wakeTime;
  var newGoToWorkTime = schedule.goToWorkTime;
  var newComeHomeTime = schedule.comeHomeTime;

  var sB = schedule.bedTime;
  var eB = schedule.wakeTime;
  var sW = schedule.goToWorkTime;
  var eW = schedule.comeHomeTime;

  var freeTimeDisplay = document.getElementById('free-time');

  var pi = Math.PI;
  var sin = Math.sin;
  var cos = Math.cos;

  var now = new Date();

  function measureTime(t1, t2) {
    // measure the amount time between two given points
    var result = 0;
    if (t1 > t2) {
      result = (24 - t1) + t2;
    } else {
      result =  t2 - t1;
    }
    return Math.round(result * 10) / 10;
  }

  var leadingZero = function (time) {
    return (time < 10) ? '0' + time : '' + time;
  };

  var convertToMinutes = function (t) {
    var min = leadingZero(parseInt((t - Math.floor(t)) * 60));
    // console.log('convertToMinutes(' + t + ') = ' + leadingZero(parseInt(t)) + ':' + min);
    return leadingZero(parseInt(t)) + ':' + min;
  };

  var convertToDecimal = function (input) {
    if (isInt(input)) {
      return '' + input;
    }
    var dec = input.split(/[.:]/);
    var h = parseInt(dec[0]);
    var m = dec[1] ? parseInt(dec[1]) / 60 : 0;
    if ((h >= 0 && h <= 23) && (m >= 0 && m <= 59)) {
      // console.log('convertToDecimal(' + input + ') = ' + '' + Math.ceil((h + m) * 100) / 100);
      return '' + Math.ceil((h + m) * 100) / 100;
    } else {
      return '';
    }
  };

  function updateDate () {
    now = new Date();
    document.getElementById('day-name').innerHTML = now.getDayName();
    document.getElementById('day-number').innerHTML=('0'+now.getDate()).slice(-2);
    document.getElementById('month-name').innerHTML = now.getMonthName();
  }

  schedule.updateDates = function () {

    schedule.bedTimeDate.setHours(parseInt(schedule.bedTime));
    schedule.bedTimeDate.setMinutes((schedule.bedTime - parseInt(schedule.bedTime)) * 60);
    schedule.bedTimeDate.setSeconds(0);
    schedule.wakeTimeDate.setHours(schedule.wakeTime);
    schedule.wakeTimeDate.setMinutes((schedule.wakeTime - parseInt(schedule.wakeTime)) * 60);
    schedule.wakeTimeDate.setSeconds(0);
    schedule.wakeTimeDate.setDate(now.getDate() + 1);

    schedule.goToWorkDate.setHours(schedule.goToWorkTime);
    schedule.goToWorkDate.setMinutes((schedule.goToWorkTime - parseInt(schedule.goToWorkTime)) * 60);
    schedule.goToWorkDate.setSeconds(0);

    schedule.comeHomeDate.setHours(schedule.comeHomeTime);
    schedule.comeHomeDate.setMinutes((schedule.comeHomeTime - parseInt(schedule.comeHomeTime)) * 60);
    schedule.comeHomeDate.setSeconds(0);

    // if bedtime is between 0 and 12, set bedtime date to tomorrow
    if (schedule.bedTime >= 0 && schedule.bedTime <= 12) {
      schedule.bedTimeDate.setDate(now.getDate() + 1);
    } else {
      schedule.bedTimeDate.setDate(now.getDate());
    }
    return 0;
  };

  schedule.updateFreeTime = function () {

    schedule.totalBed = measureTime(schedule.bedTime, schedule.wakeTime);
    schedule.totalWork = measureTime(schedule.goToWorkTime,
      schedule.comeHomeTime);
    schedule.totalPreWorkFreeTime = measureTime(schedule.wakeTime,
      schedule.goToWorkTime);
    schedule.totalPreBedFreeTime = measureTime(schedule.comeHomeTime,
      schedule.bedTime);

    schedule.freeTime = schedule.totalPreBedFreeTime +
      schedule.totalPreWorkFreeTime;
    schedule.freeTime = Math.round(schedule.freeTime * 100) / 100;

    if (isInt(schedule.freeTime)) {
      freeTimeDisplay.innerHTML = schedule.freeTime;
    } else {
      freeTimeDisplay.innerHTML = schedule.freeTime.toFixed(1);
    }

  };

  clock.getX = function (hour, radius) {
    radius = (radius) ? radius : clock.radius;
    var deg = hour * 15 - 90; // -90º so zero is at the top
    var rad = deg * pi / 180;
    return clock.centerX + (cos(rad) * radius);
  };

  clock.getY = function (hour, radius) {
    radius = (radius) ? radius : clock.radius;
    var deg = hour * 15 - 90;
    var rad = deg * pi / 180;
    return clock.centerY + (sin(rad) * radius);
  };

  clock.drawNumbers = function () {
    for (var i = 0; i < 24; i++) {
      var x = clock.getX(i, clock.radius + clock.numDistFromEdge);
      var y = clock.getY(i, clock.radius + clock.numDistFromEdge);
      var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
      text.setAttribute('x', x); // convert to string?
      text.setAttribute('y', y);
      text.setAttribute('class', 'number-label');
      text.setAttribute('text-anchor', 'middle');
      text.setAttribute('dominant-baseline', 'middle');
      text.textContent = i;
      clock.svg.appendChild(text);
    }
  };

  clock.updateHourHand = function () {
    now = new Date();
    var h = now.getHours();
    var m = now.getMinutes();
    m /= 60;
    h += m;

    var x = clock.getX(h, clock.radius - clock.hourHandDistFromEdge);
    var y = clock.getY(h, clock.radius - clock.hourHandDistFromEdge);

    clock.hourHand.setAttribute('x2', x);
    clock.hourHand.setAttribute('y2', y);

    var opp = (h + 12) % 24;

    x = clock.getX(opp, clock.hourHandLengthOfShortSide);
    y = clock.getY(opp, clock.hourHandLengthOfShortSide);

    clock.hourHandShortSide.setAttribute('x2', x);
    clock.hourHandShortSide.setAttribute('y2', y);

    // while we're at it, update the date and timer at the bottom
    updateDate();
    schedule.updateDates();
    // schedule.updateGoToWorkTimeDate();
  };

  clock.updateMinuteHand = function () {
    now = new Date();
    var s = now.getSeconds();
    var ms = now.getMilliseconds();
    s += ms / 1000;
    var q = s / 60 * 24;
    var x = clock.getX(q, clock.radius - clock.secondHandDistFromEdge);
    var y = clock.getY(q, clock.radius - clock.secondHandDistFromEdge);
    clock.secondHand.setAttribute('x2', x);
    clock.secondHand.setAttribute('y2', y);
    var opp = ((q + 12) % 24);
    x = clock.getX(opp, clock.secondHandLengthOfShortSide);
    y = clock.getY(opp, clock.secondHandLengthOfShortSide);
    clock.secondHandShortSide.setAttribute('x2', x);
    clock.secondHandShortSide.setAttribute('y2', y);
  };

  clock.drawSlice = function (slice, hourS, hourF) {

    // start
    var xS = clock.getX(hourS), yS = clock.getY(hourS);

    // finish
    var xF = clock.getX(hourF), yF = clock.getY(hourF);

    // SVG arc path nomenclature:
    // A rx ry x-axis-rotation large-arc-flag sweep-flag x y

    // Large arc flag must change like this:
    // for 7–17, we need 0 (10) < 12
    // for 5–18, we need 1 (13) > 12 between 12 and 24
    // for 17-7, we need 1 (-10) > -12 between -12 and 0
    // for 18-5, we need 0 (-13) < -12

    var newPath = 'M' + this.centerX + ' ' + this.centerY + ',' + 'L' + xS +
      ' ' + yS +',A' + this.radius + ' ' + this.radius + ' ' + '0,' +
      (((hourF-hourS) > 12 && (hourF-hourS) < 24 ) ||
      ( (hourF-hourS) > -12 && (hourF-hourS) < 0 ) ? 1 : 0) +
      ',1,' + xF + ' ' + yF + ',L ' + this.centerX + ' ' + this.centerY;

    slice.setAttribute('d', newPath);

  };

  clock.updateSlice = function () {

    clock.drawSlice(clock.sleepSlice, sB, eB);
    clock.drawSlice(clock.workSlice, sW, eW);

    var a = (24 - schedule.bedTime + newBedTime) % 24;
    var b = (24 - newBedTime + schedule.bedTime) % 24;

    // take the shortest path
    if (a < b) {
      sB = (sB + clock.increment) % 24; // clockwise
    } else if (a > b) {
      sB = sB - clock.increment; // counter-clockwise
      sB = (sB < 0) ? sB + 24 : sB;
    }
    sB = Math.round(sB * 1000) / 1000;

    a = (24 - schedule.wakeTime + newWakeTime) % 24;
    b = (24 - newWakeTime + schedule.wakeTime) % 24;

     // take the shortest path
     if (a < b) {
       // clockwise
       eB = (eB + clock.increment) % 24;
     } else if (a > b) {
       // counter-clockwise
       eB = eB - clock.increment;
       eB = (eB < 0) ? eB + 24 : eB;
    }
    eB = Math.round(eB * 1000) / 1000;

    a = (24 - schedule.goToWorkTime + newGoToWorkTime) % 24;
    b = (24 - newGoToWorkTime + schedule.goToWorkTime) % 24;

     // take the shortest path
     if (a < b) {
       // clockwise
       sW = (sW + clock.increment) % 24;
     } else if (a > b) {
       // counter-clockwise
       sW = sW - clock.increment;
       sW = (sW < 0) ? sW + 24 : sW;
    }
    sW = Math.round(sW * 1000) / 1000;

    a = (24 - schedule.comeHomeTime + newComeHomeTime) % 24;
    b = (24 - newComeHomeTime + schedule.comeHomeTime) % 24;

     // take the shortest path
     if (a < b) {
       // clockwise
       eW = (eW + clock.increment) % 24;
     } else if (a > b) {
       // counter-clockwise
       eW = eW - clock.increment;
       eW = (eW < 0) ? eW + 24 : eW;
    }
    eW = Math.round(eW * 1000) / 1000;

    var diffsB = Math.abs(sB - newBedTime);
    var diffeB = Math.abs(eB - newWakeTime);
    var diffsW = Math.abs(sW - newGoToWorkTime);
    var diffeW = Math.abs(eW - newComeHomeTime);

    if (Math.abs(diffsB < 0.1)) {
      schedule.bedTime = sB = newBedTime;
    }
    if (Math.abs(diffeB < 0.1)) {
      schedule.wakeTime = eB = newWakeTime;
    }
    if (Math.abs(diffsW < 0.1)) {
      schedule.goToWorkTime = sW = newGoToWorkTime;
    }
    if (Math.abs(diffeW < 0.1)) {
      schedule.comeHomeTime = eW = newComeHomeTime;
    }

    if (schedule.bedTime == newBedTime && schedule.wakeTime == newWakeTime &&
        schedule.goToWorkTime == newGoToWorkTime && schedule.comeHomeTime ==
          newComeHomeTime) {

      clock.drawSlice(clock.sleepSlice, schedule.bedTime, schedule.wakeTime);
      clock.drawSlice(clock.workSlice, schedule.goToWorkTime,
        schedule.comeHomeTime);
      schedule.updateFreeTime();
      schedule.updateDates();
      // schedule.updateGoToWorkTimeDate();
      timer.updateTimer();
      // timeControls.bedtimeInput.value = convertToMinutes(schedule.bedTime);
      // timeControls.waketimeInput.value = convertToMinutes(schedule.wakeTime);
      // timeControls.goToWorkInput.value = convertToMinutes(schedule.goToWorkTime);
      // timeControls.comeHomeInput.value = convertToMinutes(schedule.comeHomeTime);
    } else {
      setTimeout(clock.updateSlice, clock.delay);
    }

  };

  miniClock.drawSlice = function (sec, total) {
    var percent = total === 0 ? 0 : 1 - (sec / total);
    var deg = ((360 * percent) + 270) % 360;
    // var deg = hour * 15 - 90; // -90º so zero is at the top
    var rad = deg * pi / 180;

    var x = miniClock.centerX + (cos(rad) * miniClock.radius);
    var y = miniClock.centerY + (sin(rad) * miniClock.radius);
    
    var newPath = 'M' + this.centerX + ' ' + this.centerY + ',' + 'L' +
      x + ',' + y + ',A' + this.radius + ' ' + this.radius + ' ' + '0,' +
      ((percent > 0.5) ? '0' : '1') +',1,' + '125,0' + ',L ' +
      this.centerX + ' ' + this.centerY;

    this.slice.setAttribute('d', newPath);
  };

  // give it an amount of seconds and it will format it as total time remaining
  // and return a string
  timer.calcTime = function (seconds) {

    //find out how many hours/mins/seconds are left
    var hours = Math.floor(seconds / 3600);
    seconds -= hours * (3600);
    var minutes = Math.floor(seconds / 60);
    seconds -= minutes * (60);

    // don't show hours/minutes if we don't need them
    // if (hours > 0)
      var timeStr = (leadingZero(hours) + ':' +
        leadingZero(minutes) + ':' +
        leadingZero(seconds));
    // else if (minutes > 0)
    //   var timeStr = (leadingZero(minutes) + ':' + leadingZero(seconds));
    // else
    //   var timeStr = leadingZero(seconds);

    return timeStr;
  };

  timer.updateTimer = function () {

      var milliSecondsLeft = 0;
      var totalFreeSeconds = 0;
      now = new Date();
      // var h = now.getHours() + (now.getMinutes() / 60) + (now.getSeconds()/3600);
      // console.log(h);

      if (now >= schedule.goToWorkDate && now < schedule.comeHomeDate) {
        schedule.isAtWork = true;
        schedule.isPreWork = schedule.isPreBed = schedule.isInBed = false;
        milliSecondsLeft = schedule.comeHomeDate - now;
      } else if (now >= schedule.comeHomeDate && now < schedule.bedTimeDate) {
        schedule.isPreBed = true;
        schedule.isPreWork = schedule.isAtWork = schedule.isInBed = false;
        milliSecondsLeft = schedule.bedTimeDate - now;
      } else if (now >= schedule.bedTimeDate && now < schedule.wakeTimeDate) {
        schedule.isInBed = true;
        schedule.isPreWork = schedule.isPreBed = schedule.isAtWork = false;
        milliSecondsLeft = schedule.wakeTimeDate - now;
      } else if (now >= schedule.wakeTimeDate && now < schedule.goToWorkDate) {
        schedule.isPreWork = true;
        schedule.isPreBed = schedule.isAtWork = schedule.isInBed = false;
        milliSecondsLeft = schedule.goToWorkDate - now;
      }

      var secondsLeft = Math.round(milliSecondsLeft / 1000);
      var t = 0;

      if (schedule.isPreWork) {
        timer.label.innerHTML = 'Time until work';
        totalFreeSeconds = schedule.totalPreWorkFreeTime * 3600;
        t = secondsLeft / 3600;
        schedule.totalHoursRemainingUntilNextThing = Math.round(t * 10) / 10;
        miniClock.drawSlice(secondsLeft, totalFreeSeconds);
        miniClock.busy.style.display = 'none';
      } else if (schedule.isPreBed) {
        timer.label.innerHTML = 'Time until bedtime';
        totalFreeSeconds = schedule.totalPreBedFreeTime * 3600;
        t = secondsLeft / 3600;
        schedule.totalHoursRemainingUntilNextThing = Math.round(t * 10) / 10;
        miniClock.drawSlice(secondsLeft, totalFreeSeconds);
        miniClock.busy.style.display = 'none';
      } else if (schedule.isAtWork) {
        timer.label.innerHTML = 'Time until finish work';
        miniClock.busy.innerHTML = 'WORKING';
        miniClock.drawSlice(secondsLeft, totalFreeSeconds);
      } else if (schedule.isInBed) {
        timer.label.innerHTML = 'Time until wake up';
        miniClock.busy.innerHTML = 'SLEEPING';
        miniClock.drawSlice(secondsLeft, totalFreeSeconds);
      }

      // if past bedTime, set to zero
      // if (secondsLeft <= 0) {
      //   timer.display.innerHTML = '00:00:00'
      // } else {
        timer.display.innerHTML = timer.calcTime(secondsLeft);
      // }
  };



  window.onload = function() {

    updateDate();
    schedule.updateFreeTime();
    schedule.updateDates();
    clock.drawNumbers();
    clock.updateHourHand();
    clock.updateMinuteHand();
    clock.drawSlice(clock.sleepSlice, schedule.bedTime, schedule.wakeTime);
    clock.drawSlice(clock.workSlice, schedule.goToWorkTime,
      schedule.comeHomeTime);
    timer.updateTimer();

    // set default values
    timeControls.bedtimeInput.value = convertToMinutes(schedule.bedTime);
    timeControls.waketimeInput.value = convertToMinutes(schedule.wakeTime);
    timeControls.goToWorkInput.value = convertToMinutes(schedule.goToWorkTime);
    timeControls.comeHomeInput.value = convertToMinutes(schedule.comeHomeTime);

    // get timer to show time left before first interval kicks in
    now = new Date();
    var h = now.getHours();
    var milliSecondsLeft = 0;
    if (h >= schedule.wakeTime && h < schedule.goToWorkTime) {
      milliSecondsLeft = schedule.goToWorkDate - now;
      timer.label.innerHTML = 'Time until work';
    } else {
      milliSecondsLeft = schedule.bedTimeDate - now;
      timer.label.innerHTML = 'Time until bedtime';
    }
    var secondsLeft = Math.round(milliSecondsLeft / 1000);
    if (secondsLeft <= 0) {
      timer.display.innerHTML = '00:00:00';
    } else {
      timer.display.innerHTML = timer.calcTime(secondsLeft);
    }

    // timer (time left until bedTime)
    var timerInterval = setInterval(function() {
      timer.updateTimer();
    }, 1000);

    // timer (time left until bedTime)
    var secondHandInterval = setInterval(function() {
      clock.updateMinuteHand();
    }, 16);


    // hour hand – do this every 30000ms = 30s
    var hourHandInterval = setInterval(function() {
      clock.updateHourHand();
    }, 30000);

  }; // ======== end of window.onload


  function inputIsOK(input, type) {

    if (isInt(input) && input >= 0 && input < 24) {

      var sleepCrossesZero = (schedule.bedTime > schedule.wakeTime) ?
          true : false;
      var workCrossesZero = (schedule.goToWorkTime > schedule.comeHomeTime) ?
          true : false;

      // switch (type) {
      //   case 'bed':
      //     if (workCrossesZero) {
      //       if (input >= schedule.wakeTime || input < schedule.comeHomeTime) {
      //         alert('errorz. work crosses zero.');
      //         return false;
      //       }
      //     } else {
      //       if (input >= schedule.wakeTime || input < schedule.comeHomeTime) {
      //         alert('errorz. no cross.');
      //         return false;
      //       }
      //     }
      //     break;
      //   case 'wake':
      //     if (workCrossesZero) {
      //       if (input > schedule.goToWorkTime || input <= schedule.bedTime) {
      //         alert('errorz. work crosses zero');
      //         return false;
      //       }
      //     } else {
      //       if (input > schedule.goToWorkTime || input <= schedule.bedTime) {
      //         alert('errorz. no cross.');
      //         return false;
      //       }
      //     }
      //     break;
      //   case 'work':
      //     if (sleepCrossesZero) {
      //       if (input >= schedule.comeHomeTime || input < schedule.wakeTime) {
      //         alert('errorz. SCZ');
      //         return false;
      //       }
      //     } else {
      //       if (input >= schedule.comeHomeTime || input < schedule.wakeTime) {
      //         alert('errorz. no cross');
      //         return false;
      //       }
      //     }
      //     break;
      //   case 'home':
      //     if (sleepCrossesZero) {
      //       if (input > schedule.bedTime || input <= schedule.goToWorkTime) {
      //         alert('errorz. SCZ');
      //         return false;
      //       }
      //     } else {
      //       if (input > schedule.bedTime || input <= schedule.goToWorkTime) {
      //         alert('errorz. no cross');
      //         return false;
      //       }
      //     }
      //     break;
      // }

      return true;
    } else {
      return false;
    }
  }


  function handleBedtimeInputChange(e) {
    if (e.keyCode == 13) {
      var x = convertToDecimal(timeControls.bedtimeInput.value);
      if (inputIsOK(x, 'bed')) {
        newBedTime = parseFloat(x);
        clock.updateSlice();
      }
    }
    return false;
  }

  function handleWaketimeInputChange(e) {
    if (e.keyCode == 13) {
      var x = convertToDecimal(timeControls.waketimeInput.value);
      if (inputIsOK(x, 'wake')) {
        newWakeTime = parseFloat(x);
        clock.updateSlice();
      }
    }
    return false;
  }

  function handleGoToWorkInputChange(e) {
    if (e.keyCode == 13) {
      var x = convertToDecimal(timeControls.goToWorkInput.value);
      if (inputIsOK(x, 'work')) {
        newGoToWorkTime = parseFloat(x);
        clock.updateSlice();
      }
    }
    return false;
  }

  function handleComeHomeInputChange(e) {
    if (e.keyCode == 13) {
      var x = convertToDecimal(timeControls.comeHomeInput.value);
      if (inputIsOK(x, 'home')) {
        newComeHomeTime = parseFloat(x);
        clock.updateSlice();
      }
    }
    return false;
  }

  timeControls.bedtimeInput.addEventListener('keypress', handleBedtimeInputChange, false);
  timeControls.waketimeInput.addEventListener('keypress', handleWaketimeInputChange, false);
  timeControls.goToWorkInput.addEventListener('keypress', handleGoToWorkInputChange, false);
  timeControls.comeHomeInput.addEventListener('keypress', handleComeHomeInputChange, false);

  // bedtimeInput.addEventListener('blur', handleBedtimeInputChange, false);
  // waketimeInput.addEventListener('blur', handleWaketimeInputChange, false);
  // goToWorkInput.addEventListener('blur', handleGoToWorkInputChange, false);
  // comeHomeInput.addEventListener('blur', handleComeHomeInputChange, false);

  $('#bedtime').blur(function(e){
    var x = convertToDecimal(timeControls.bedtimeInput.value);
    if (inputIsOK(x, 'bed')) {
      newBedTime = parseFloat(x);
      timeControls.bedtimeInput.value = convertToMinutes(x);
      clock.updateSlice();
    }
  });

  $('#waketime').blur(function(e){
    var x = convertToDecimal(timeControls.waketimeInput.value);
    if (inputIsOK(x, 'wake')) {
      newWakeTime = parseFloat(x);
      timeControls.waketimeInput.value = convertToMinutes(x);
      clock.updateSlice();
    }
  });

  $('#go-to-work').blur(function(e){
    var x = convertToDecimal(timeControls.goToWorkInput.value);
    if (inputIsOK(x, 'work')) {
      newGoToWorkTime = parseFloat(x);
      timeControls.goToWorkInput.value = convertToMinutes(x);
      clock.updateSlice();
    }
  });

  $('#come-home').blur(function(e){
    var x = convertToDecimal(timeControls.comeHomeInput.value);
    if (inputIsOK(x, 'home')) {
      newComeHomeTime = parseFloat(x);
      timeControls.comeHomeInput.value = convertToMinutes(x);
      clock.updateSlice();
    }
  });

  $('.slice').mouseenter(function(){
    if (this.id == 'work-slice') {
      $('.tooltip-label.main').text('Work');
      $('.tooltip-data.main').text(schedule.totalWork);
      $('.tooltip-hrs.main').text('hrs');
      $('.tooltip.main').show();
    } else if (this.id == 'sleep-slice') {
      $('.tooltip-label.main').text('Sleep');
      $('.tooltip-data.main').text(schedule.totalBed);
      $('.tooltip-hrs.main').text('hrs');
      $('.tooltip.main').show();
    } else if (this.id == 'mini-clock-slice') {
      $('.tooltip-label.mini').text('Remaining');
      // what about pre work?
      $('.tooltip-data.mini').text(schedule.totalHoursRemainingUntilNextThing);
      $('.tooltip-hrs.mini').text('hrs');
      $('.tooltip.mini').show();
    } else if (this.id == 'mini-clock-face') {
      $('.tooltip-label.mini').text('Total');
      // what about pre work?
      $('.tooltip-data.mini').text(schedule.totalPreBedFreeTime);
      $('.tooltip-hrs.mini').text('hrs');
      $('.tooltip.mini').show();
    }
  });

  $('.slice').bind('mousemove', function(e){
    $('.tooltip').offset({
      left: e.pageX + 5,
      top: e.pageY + 5
    });
  });

  $('.slice').mouseout(function(){
    $('.tooltip').hide();
  });


})();

            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console