<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
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |