Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Canvas Clock - CanJS 3.1">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<canvas id="analog"  width="255" height="255"></canvas>
<script type="text/stache" id="digital-template">
  <div class='controls'>
    <button ($click)='start()'
      {$disabled}="isStopped">Start</button>
    <button ($click)='stop()'
      {$disabled}="not(~isStopped)">Stop</button>
  </div>
  <div class='digital'>{{hh}}:{{mm}}:{{ss}}</div>
</script>
<script src="https://unpkg.com/can/dist/global/can.all.js"></script>
</body>
</html>
 
.digital {
  font-family: monospace;
  float: left;
  font-size: 60px;
  padding: 90px 10px;
  margin: 0px 20px 0px 0px;
  border: solid 1px black;
  float: left;
}
#analog {float: left;}
.controls {
  padding: 20px;
  float: left;
}
 
var pad = function(n){
  n = ""+n;
  return n.length <= 1 ? "0"+n : n;
};
var Timer = can.DefineMap.extend({
  time: {Value: Date, Type: Date},
  interval: "number",
  start: function(){
    var self = this;
    this.interval = setInterval(function(){
      self.time = new Date(self.time.getTime() + 5 );
    },5);
  },
  stop: function(){
    clearInterval(this.interval);
    this.interval = null;
  },
  get isStopped(){
    return !!this.interval;
  },
  get hh(){
    var hr= this.time.getHours() % 12
    return hr === 0 ? 12 : hr;
  },
  get mm(){
    return pad(this.time.getMinutes() )
  },
  get ss(){
    return pad(this.time.getSeconds())
  }
});
var Analog = function(element, timer){
  this.canvas = element.getContext('2d');
  this.rad = 250;
  this.radius = this.rad/2 - 5;
  this.center = this.rad/2;
  timer.on("time", this.drawClock.bind(this));
}
Analog.prototype.drawNeedle = function(size, dist, styles) {
  var theta = (6 * Math.PI / 180),
      x = this.center + size * Math.cos(dist * theta - Math.PI/2),
      y = this.center + size * Math.sin(dist * theta - Math.PI/2);
  Object.assign(this.canvas, styles)
  this.canvas.beginPath();
  this.canvas.moveTo(x,y);
  this.canvas.lineTo(this.center,this.center);
  this.canvas.closePath();
  this.canvas.stroke();
}
Analog.prototype.drawClock = function(ev, newTime){
  var seconds = newTime.getSeconds()
        
  // draw circle
  this.canvas.clearRect(0,0,this.center*2,this.center*2);
  this.canvas.lineWidth = 4.0;
  this.canvas.strokeStyle = "#567";
  this.canvas.beginPath();
  this.canvas.arc(this.center,this.center,this.radius,0,Math.PI * 2,true);
  this.canvas.closePath();
  this.canvas.stroke();
  // draw second hand
  var dist = newTime.getSeconds()+ ((newTime.getTime() % 1000) / 1000)
  this.drawNeedle(
    this.center * 0.80,
    newTime.getSeconds(),
    {
      lineWidth:  2.0,
      strokeStyle: "#FF0000",
      lineCap: "round"
    }
  );
  // draw minute hand
  this.drawNeedle(
    this.center * 0.65,
    dist = newTime.getMinutes() + dist/ 60,
    {
      lineWidth:  3.0,
      strokeStyle: "#423",
      lineCap: "round"
    }
  );
  this.drawNeedle(
    this.center * 0.40,
    newTime.getHours() * 60 / 12 + dist / 60,
    {
      lineWidth:  4.0,
      strokeStyle: "#42F",
      lineCap: "round"
    }
  );
}
var timer = new Timer();
timer.start();
new Analog(document.getElementById("analog"), timer);
var template = can.stache.from("digital-template");
var frag = template(timer);
document.body.appendChild(frag);
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
justinbmeyerpro
0viewers