|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://unpkg.com/d3@4"></script> |
|
<script src="https://unpkg.com/d3-component@3"></script> |
|
</head> |
|
<body> |
|
<script> |
|
var clock = (function (){ |
|
var timerLocal = d3.local(); |
|
return d3.component("svg") |
|
.create(function (selection, d){ |
|
var width = d.width, |
|
height = d.height, |
|
side = Math.min(width, height), |
|
outerCircleStrokeWidth = side * d.outerCircleThickness, |
|
centralCircleRadius = side * d.centralCircleSize, |
|
midnight = d3.timeDay(new Date()).getTime(), |
|
second = 1000, |
|
minute = second * 60, |
|
hour = minute * 60, |
|
day = hour * 12; |
|
|
|
// Update SVG dimensions. |
|
selection |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
// Outer circle. |
|
selection.append("circle") |
|
.attr("cx", width / 2) |
|
.attr("cy", height / 2) |
|
.attr("r", side / 2 - outerCircleStrokeWidth) |
|
.attr("fill", "none") |
|
.attr("stroke", "black") |
|
.attr("stroke-width", outerCircleStrokeWidth); |
|
|
|
// Central circle. |
|
selection.append("circle") |
|
.attr("cx", width / 2) |
|
.attr("cy", height / 2) |
|
.attr("r", centralCircleRadius); |
|
|
|
function hand(handLength, handWidth, color){ |
|
var spindle = selection.append("g") |
|
.attr("transform", "translate(" + width/2 + "," + height/2 + ")") |
|
.append("g"); |
|
spindle.append("line") |
|
.attr("x2", side / 2 * handLength) |
|
.attr("stroke", color || "black") |
|
.attr("stroke-width", side * handWidth); |
|
return spindle; |
|
} |
|
|
|
var hourHand = hand(d.hourHandLength, d.hourHandWidth), |
|
minuteHand = hand(d.minuteHandLength, d.minuteHandWidth), |
|
secondHand = hand(d.secondHandLength, d.secondHandWidth), |
|
millisecondHand = hand(d.msHandLength, d.msHandWidth, "white"); |
|
|
|
function angle(ms, timespan){ |
|
return (ms / timespan % 1) * 360 - 90; |
|
} |
|
|
|
timerLocal.set(selection.node(), d3.timer(function (){ |
|
var ms = Date.now() - midnight; |
|
hourHand.attr("transform", "rotate(" + angle(ms, day) + ")"); |
|
minuteHand.attr("transform", "rotate(" + angle(ms, hour) + ")"); |
|
secondHand.attr("transform", "rotate(" + angle(ms, minute) + ")"); |
|
millisecondHand.attr("transform", "rotate(" + angle(ms, second) + ")"); |
|
})); |
|
}) |
|
.destroy(function (selection){ |
|
timerLocal.get(selection.node()).stop(); |
|
}); |
|
}()); |
|
|
|
d3.select("body") |
|
.call(clock, { |
|
width: 960, |
|
height: 500, |
|
outerCircleThickness: 0.01, |
|
centralCircleSize: 0.04, |
|
hourHandLength: 0.7, |
|
hourHandWidth: 0.03, |
|
minuteHandLength: 0.85, |
|
minuteHandWidth: 0.015, |
|
secondHandLength: 0.9, |
|
secondHandWidth: 0.005, |
|
msHandLength: 0.08, |
|
msHandWidth: 0.004 |
|
}); |
|
|
|
</script> |
|
</body> |