Based on PolarClock
forked from syntagmatic's block: Polar Clock
license: mit |
Based on PolarClock
forked from syntagmatic's block: Polar Clock
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
background: #111; | |
font: 10px Helvetica; | |
margin: auto; | |
position: relative; | |
width: 960px; | |
} | |
text { | |
text-anchor: middle; | |
alignment-baseline: middle; | |
fill: #fff; | |
} | |
.hours { | |
stroke: none; | |
fill: none; | |
} | |
.hour text { | |
fill: #fff; | |
font-size: 12px; | |
} | |
.hour line { | |
stroke: #fff; | |
} | |
.minute text { | |
fill: #666; | |
font-size: 8px; | |
} | |
.minute line { | |
stroke: #666; | |
} | |
</style> | |
<body> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500, | |
radius = 94; | |
var arc = d3.svg.arc() | |
.startAngle(0) | |
.endAngle(function(d) { return d.value * 2 * Math.PI; }) | |
.innerRadius(function(d) { return (3*d.index) * radius; }) | |
.outerRadius(function(d) { return (3*d.index + d.spacing) * radius; }); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
.append("g") | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); | |
var field = svg.selectAll("g") | |
.data(fields) | |
.enter().append("g") | |
.attr("class", "field"); | |
field.append("path"); | |
field.append("text"); | |
// minute hands | |
var minutedomain = d3.range(60); | |
var minuteangle = d3.scale.linear() | |
.domain([0,60]) | |
.range([180,-180]) | |
var minutemarks = svg.selectAll(".minute.axis") | |
.data(minutedomain) | |
.enter().append("g") | |
.attr("class", "minute") | |
.attr("transform", function(d) { return "rotate(" + -minuteangle(d) + ")"; }) | |
minutemarks | |
.filter(function(d) { return d % 5 == 0; }) | |
.append("text") | |
.attr("y", 190) | |
.attr("transform", function(d) { | |
return "rotate(" + minuteangle(d) + ",0,190)"; | |
}) | |
.text(String); | |
minutemarks | |
.append("line") | |
.attr("x1", 168) | |
.attr("x2", 180) | |
.attr("y1", 0) | |
.attr("y2", 0); | |
// hour hands | |
var hourdomain = d3.range(12); | |
var hourangle = d3.scale.linear() | |
.domain([0,12]) | |
.range([180,-180]) | |
var hourmarks = svg.selectAll(".hour.axis") | |
.data(hourdomain) | |
.enter().append("g") | |
.attr("class", "hour") | |
.attr("transform", function(d) { return "rotate(" + -hourangle(d) + ")"; }) | |
hourmarks | |
.append("text") | |
.attr("y", 142) | |
.attr("transform", function(d) { | |
return "rotate(" + hourangle(d) + ",0,142)"; | |
}) | |
.text(String); | |
hourmarks | |
.append("line") | |
.attr("x1", 156) | |
.attr("x2", 180) | |
.attr("y1", 0) | |
.attr("y2", 0); | |
var counter = 0; | |
function tick() { | |
if (counter++ % 3 != 0) return; // ease up on cpu | |
field.data(fields) | |
.select("path") | |
.attr("d", arc) | |
.style("fill", function(d) { return d.color; }); | |
} | |
d3.timer(tick); | |
function fields() { | |
var now = new Date; | |
var milliseconds = now.getMilliseconds(); | |
var seconds = now.getSeconds() + milliseconds / 1000; | |
var minutes = now.getMinutes() + seconds / 60; | |
var hours = ((now.getHours() + 24) % 12 || 0) + minutes / 60; | |
return [ | |
{field: "seconds", color: "#c22", index: .6348, spacing: 0.015, value: seconds / 60}, | |
{field: "minutes", color: "#555", index: .597, spacing: 0.115, value: minutes / 60}, | |
{field: "hours", color: "#888", index: .555, spacing: 0.1, value: hours / 12} | |
]; | |
} | |
</script> |