3D CSS digital clock

Move the mouse. Do it.

by amyseqmedia

HTML

<!doctype html>
<html>
  <head>
    <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="index.css">
  </head>
  <body>
    <div class="stop-moving">
      <label><input type="checkbox" id="stop-moving"> Stop moving!</label>
    </div>
    <div class="clocks">
      <div class="clock clock1">
        <ul>
          <li class="digit digit1">
            <div class="bar bar0"></div>
            <div class="bar bar1"></div>
            <div class="bar bar2"></div>
            <div class="bar bar3"></div>
            <div class="bar bar4"></div>
            <div class="bar bar5"></div>
            <div class="bar bar6"></div>
          </li>
          <li class="digit digit2">
            <div class="bar bar0"></div>
            <div class="bar bar1"></div>
            <div class="bar bar2"></div>
            <div class="bar bar3"></div>
            <div class="bar bar4"></div>
            <div class="bar bar5"></div>
            <div class="bar bar6"></div>
          </li>
          <li class="separator">:</li>
          <li class="digit digit3">
            <div class="bar bar0"></div>
            <div class="bar bar1"></div>
            <div class="bar bar2"></div>
            <div class="bar bar3"></div>
            <div class="bar bar4"></div>
            <div class="bar bar5"></div>
            <div class="bar bar6"></div>
          </li>
          <li class="digit digit4">
            <div class="bar bar0"></div>
            <div class="bar bar1"></div>
            <div class="bar bar2"></div>
            <div class="bar bar3"></div>
            <div class="bar bar4"></div>
            <div class="bar bar5"></div>
            <div class="bar bar6"></div>
          </li>
          <li class="digit digit5">
            <div class="bar bar0"></div>
            <div class="bar bar1"></div>
            <div class="bar bar2"></div>
            <div class="bar bar3"></div>
           ...

CSS

body {
  -webkit-perspective: 1000;
  -moz-perspective: 1000;
  perspective: 1000;
  font-family: 'Source Sans Pro', sans-serif;
  -webkit-transform: scale(0.8, 0.8) translate(0, -20px);
  -moz-transform: scale(0.8, 0.8) translate(0, -20px);
  transform: scale(0.8, 0.8) translate(0, -20px);
}

.byline {
  text-align: center;
  margin-top: 100px;
}

.byline a {
  text-decoration: none;
  cursor: pointer;
}

.clock {
  width: 700px;
  height: 350px;
  border-radius: 10px;
  background: #000;
  margin: 0px auto;
  text-align: center;
  padding-top: 30px;
  color: #2df;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.clock2 {
  -webkit-transform: rotateX(180deg);
  transform: rotateX(180deg);
}

.clock .off {
  -webkit-transition: all 0.2s linear;
  -moz-transition: all 0.2s linear;
  transition: all 0.2s linear;
  opacity: 0.2;
}

.clock .fadeout {
  background: linear-gradient(to bottom, rgba(255,255,255,1), rgba(255,255,255, 0.8));
  background-image: -webkit-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255, 0.8));
  position: absolute;
  top: 0px;
  left: 0px;
  width: 700px;
  height: 350px;
}

.clock ul {
  margin: 0;
  padding: 0;
  position: relative;
}

.clock ul li {
  list-style: none;
  display: inline-block;
  position: relative;
  top: 30px;  
  margin: 0;
  padding: 0;
  width: 120px;
  height: 200px;
}

.clock ul li.ampm {
  position: absolute;
  bottom: 160px;
  right: 50px;
  height: 10px;
    width: 30px;
}

.clock ul li.ampm.pm {
  top: 208px;
}

.clock ul li.separator {
  font-size: 100px;
  height: 150px;
  width: 40px;
  position: relative;
  top: -42px;
}

.clock ul li.digit {
  font-size: 200px;
}

.clock ul li.digit5, .clock ul li.digit6 {
  position: absolute;
  left: 570px;
  -webkit-transform: scale(0.1, 0.1);
  -moz-transform: scale(0.1, 0.1);
  transform: scale(0.1, 0.1);
}

.clock ul li.digit6 {
  left: 585px;
}

.clock .bar {
  position: absolute;
  border-radius: 10px;
 ...

JavaScript

var DIGIT_BITMAP = [
  [1, 1, 1, 0, 1, 1, 1],     // 0
  [0, 0, 1, 0, 0, 1, 0],
  [1, 0, 1, 1, 1, 0, 1],     // 2
  [1, 0, 1, 1, 0, 1, 1],
  [0, 1, 1, 1, 0, 1, 0],     // 4
  [1, 1, 0, 1, 0, 1, 1],
  [1, 1, 0, 1, 1, 1, 1],     // 6
  [1, 0, 1, 0, 0, 1, 0],
  [1, 1, 1, 1, 1, 1, 1],     // 8
  [1, 1, 1, 1, 0, 1, 1]
];

function $q(selector, context) {
  return (context || document).querySelector(selector);
}

function setDigit(context, which, value) {
  var $digit = $q(".digit" + which, context);
  for (var bar = 0; bar <= 6; bar++) {
    var $bar = $q(".bar" + bar, $digit);
    if (DIGIT_BITMAP[value][bar] === 0) {
      addClass($bar, "off");
    } else {
      removeClass($bar, "off");
    }
  }
}

function addClass(element, klass) {
  if (!hasClass(element, klass)) {
    element.className = (element.className || '') + " " + klass;
  }
}

function removeClass(element, klass) {
  if (hasClass(element, klass)) {
    // Pad out w/ delimiters to isolate classname.
    element.className = (" " + (element.className || '') + " ").
        replace(" " + klass + " ", "").
        replace(/^\s+/, '').
        replace(/\s+$/, '');
  }
}

function hasClass(element, klass) {
  var classes = (element.className || '').split(/\s/);

  for (var i = 0; i < classes.length; i++) {
    if (classes[i] === klass) {
      return true;
    }
  }

  return false;
}

function update(context) {
  var d = new Date(),
      hh = d.getHours(),
      mm = d.getMinutes(),
      ss = d.getSeconds(),
      hours = [],
      minutes =[];
      
  if (hh > 12) {
    hh -= 12;
    addClass($q(".am", context), "off");
    removeClass($q(".pm", context), "off");
  } else {
    removeClass($q(".am", context), "off");
    addClass($q(".pm", context), "off");
  }
  
  setDigit(context, 1, Math.floor(hh/10));
  setDigit(context, 2, hh % 10);
  setDigit(context, 3, Math.floor(mm/10));
  setDigit(context, 4, mm % 10);
  setDigit(context, 5, Math.floor(ss/10));
  setDigit(context, 6, ss % 10);

 ...