paulo@62: <!DOCTYPE html>
paulo@62: <meta charset="utf-8">
paulo@62: 
paulo@62: 
paulo@62: <style>
paulo@62: 
paulo@62: body {
paulo@62: 	background-color: #FFF;
paulo@62: }
paulo@62: 
paulo@62: text.digital {
paulo@62: 	font-family: sans-serif;
paulo@62: 	fill: #777;
paulo@62: }
paulo@62: 
paulo@62: .analog.seconds {
paulo@62: 	fill: #CCC;
paulo@62: }
paulo@62: 
paulo@62: .analog.minutes {
paulo@62: 	fill: #AAA;
paulo@62: }
paulo@62: 
paulo@62: .analog.hours {
paulo@62: 	fill: #999;
paulo@62: }
paulo@62: 
paulo@62: .analog.past {
paulo@62: 	fill: #EEE;
paulo@62: }
paulo@62: 
paulo@62: </style>
paulo@62: 
paulo@62: 
paulo@62: <script src="d3.min.js"></script>
paulo@62: 
paulo@62: 
paulo@62: <svg></svg>
paulo@62: 
paulo@62: 
paulo@62: <script>
paulo@62: 
paulo@62: var TAU = 2*Math.PI;
paulo@62: var margin = 10;
paulo@62: 
paulo@62: var minutes_seconds_scale = d3.scale.linear()
paulo@62: 	.domain([0, 60])
paulo@62: 	.range([0, TAU]);
paulo@62: 
paulo@62: var hours_scale = d3.scale.linear()
paulo@62: 	.domain([0, 24])
paulo@62: 	.range([0, TAU]);
paulo@62: 
paulo@62: var tf = function(x) { return d3.format("02d")(Math.floor(x)) };
paulo@62: 
paulo@62: var render = function() {
paulo@62: 	var ct = new Date();
paulo@62: 	var milliseconds = ct.getMilliseconds();
paulo@62: 	var seconds = ct.getSeconds() + (milliseconds/1000.0);
paulo@62: 	var minutes = ct.getMinutes() + (seconds/60.0);
paulo@62: 	var hours = ct.getHours() + (minutes/60.0);
paulo@62: 	
paulo@62: 	var r = (Math.min(window.innerWidth, window.innerHeight)/2) - margin;
paulo@62: 	
paulo@62: 	var or_seconds = r;
paulo@62: 	var ir_seconds = r*0.75;
paulo@62: 
paulo@62: 	var or_minutes = r*0.7;
paulo@62: 	var ir_minutes = r*0.45;
paulo@62: 
paulo@62: 	var or_hours = r*0.4;
paulo@62: 	var ir_hours = r*0.15;
paulo@62: 
paulo@62: 	var digital_text_scale = 0.75;
paulo@62: 	
paulo@62: 	var svg = d3.select("svg")
paulo@62: 			.attr("width", 2*(r + margin))
paulo@62: 			.attr("height", 2*(r + margin));
paulo@62: 
paulo@62: 	svg.selectAll("g").remove();
paulo@62: 
paulo@62: 	svg = svg.append("g")
paulo@62: 			.attr("transform", "translate(" + margin + "," + margin + ")");
paulo@62: 
paulo@62: 	//svg.append("text")
paulo@62: 	//	.text(d3.time.format("%X")(ct));
paulo@62: 
paulo@62: 	var c = svg.append("g")
paulo@62: 			.attr("transform", "translate(" + r + "," + r + ")");
paulo@62: 
paulo@62: 	c.append("path")
paulo@62: 		.attr("class", "analog seconds")
paulo@62: 		.attr("d", d3.svg.arc()
paulo@62: 			.outerRadius(or_seconds)
paulo@62: 			.innerRadius(ir_seconds)
paulo@62: 			.startAngle(0)
paulo@62: 			.endAngle(minutes_seconds_scale(seconds))
paulo@62: 		);
paulo@62: 	c.append("path")
paulo@62: 		.attr("class", "analog seconds past")
paulo@62: 		.attr("d", d3.svg.arc()
paulo@62: 			.outerRadius(or_seconds)
paulo@62: 			.innerRadius(ir_seconds)
paulo@62: 			.startAngle(minutes_seconds_scale(seconds))
paulo@62: 			.endAngle(TAU)
paulo@62: 		);
paulo@62: 	c.append("text")
paulo@62: 		.attr("class", "digital")
paulo@62: 		.attr("x", ir_seconds)
paulo@62: 		.attr("font-size", (or_seconds - ir_seconds)*digital_text_scale + "px")
paulo@62: 		.text(tf(seconds));
paulo@62: 
paulo@62: 	c.append("path")
paulo@62: 		.attr("class", "analog minutes")
paulo@62: 		.attr("d", d3.svg.arc()
paulo@62: 			.outerRadius(or_minutes)
paulo@62: 			.innerRadius(ir_minutes)
paulo@62: 			.startAngle(0)
paulo@62: 			.endAngle(minutes_seconds_scale(minutes))
paulo@62: 		);
paulo@62: 	c.append("path")
paulo@62: 		.attr("class", "analog minutes past")
paulo@62: 		.attr("d", d3.svg.arc()
paulo@62: 			.outerRadius(or_minutes)
paulo@62: 			.innerRadius(ir_minutes)
paulo@62: 			.startAngle(minutes_seconds_scale(minutes))
paulo@62: 			.endAngle(TAU)
paulo@62: 		);
paulo@62: 	c.append("text")
paulo@62: 		.attr("class", "digital")
paulo@62: 		.attr("x", ir_minutes)
paulo@62: 		.attr("font-size", (or_minutes - ir_minutes)*digital_text_scale + "px")
paulo@62: 		.text(tf(minutes));
paulo@62: 
paulo@62: 	c.append("path")
paulo@62: 		.attr("class", "analog hours")
paulo@62: 		.attr("d", d3.svg.arc()
paulo@62: 			.outerRadius(or_hours)
paulo@62: 			.innerRadius(ir_hours)
paulo@62: 			.startAngle(0)
paulo@62: 			.endAngle(hours_scale(hours))
paulo@62: 		);
paulo@62: 	c.append("path")
paulo@62: 		.attr("class", "analog hours past")
paulo@62: 		.attr("d", d3.svg.arc()
paulo@62: 			.outerRadius(or_hours)
paulo@62: 			.innerRadius(ir_hours)
paulo@62: 			.startAngle(hours_scale(hours))
paulo@62: 			.endAngle(TAU)
paulo@62: 		);
paulo@62: 	c.append("text")
paulo@62: 		.attr("class", "digital")
paulo@62: 		.attr("x", ir_hours)
paulo@62: 		.attr("font-size", (or_hours - ir_hours)*digital_text_scale + "px")
paulo@62: 		.text(tf(hours));
paulo@62: 
paulo@62: 
paulo@62: }
paulo@62: 
paulo@62: window.setInterval(render, 1000);
paulo@62: 
paulo@62: 
paulo@62: </script>