Skip to content

Instantly share code, notes, and snippets.

@ahmetkizilay
Created June 23, 2014 18:44
Show Gist options
  • Save ahmetkizilay/b3266198301e6ab46288 to your computer and use it in GitHub Desktop.
Save ahmetkizilay/b3266198301e6ab46288 to your computer and use it in GitHub Desktop.
analog clock implemented with d3
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
@import url(http://fonts.googleapis.com/css?family=PT+Sans);
body {
background-color: #ddd;
font-family: 'PT Sans', sans-serif;
}
svg {
border: 1px solid black;
background-color: white;
}
circle {
fill: #999999;
fill-opacity: 0.8;
stroke: #4d4d4d;
}
.center-text {
alignment-baseline: middle;
text-anchor: middle;
font: 18px;
font-weight: bold;
fill: #4d4d4d;
}
.second {
fill: #b2182b;
}
.minute {
fill: #ef8a62;
}
.hour {
fill: #fddbc7;
}
.knob {
fill: black;
fill-opacity: 0.9;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<script>
var width = 400,
height = 400,
halfWidth = width / 2,
halfHeight = height / 2;
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
var circle_count = 12;
var big_radius = 160;
var radius = 20;
var angular_increment = 2.0 * Math.PI / circle_count;
var jitterFunc = function() {
var me = this;
me.transition()
.duration(100)
.ease('in-out')
.attr("cx", (Math.random() * 2.0 - 1.0))
.attr("cy", (Math.random() * 2.0 - 1.0))
.each("end", function () {
jitterFunc.call(me);
});
}
var animateSecondHand = function () {
var currentSecond = new Date().getSeconds();
var rotationAngle = currentSecond * 6;
var me = this;
me.transition()
.duration(1000)
.attr("transform", "rotate(" + rotationAngle + ")")
.each("end", function () {
animateSecondHand.call(me);
});
}
var animateMinuteHand = function () {
var currentMinute = new Date().getMinutes();
var rotationAngle = currentMinute * 6;
var me = this;
me.transition()
.duration(500)
.attr("transform", "rotate(" + rotationAngle + ")")
.each("end", function () {
animateMinuteHand.call(me);
});
}
var calculateHourAngle = function () {
var currentDate = new Date();
var currentHour = currentDate.getHours();
var currentMinute = currentDate.getMinutes();
return ((currentHour % 12) * 30) + Math.floor(currentMinute * 0.5);
}
var animateHourHand = function () {
var rotationAngle = calculateHourAngle();
var me = this;
me.transition()
.duration(500)
.attr("transform", "rotate(" + rotationAngle + ")")
.each("end", function () {
animateHourHand.call(me);
});
}
// let's draw 12 circles around a circle
for(var i = 0; i < circle_count; i += 1) {
var center_x = halfWidth + big_radius * Math.cos((i * angular_increment) - (Math.PI * 0.5));
var center_y = halfHeight + big_radius * Math.sin((i * angular_increment) - (Math.PI * 0.5));
var group = svg.append("g")
.attr("transform", "translate(" + center_x + ", " + center_y + ")");
var circle = group.append("circle")
.attr("r", radius);
var text = group.append("text")
.attr("class", "center-text")
.text(i == 0 ? 12 : i);
}
var hourHand = svg.append("g")
.attr("transform", "translate(" + halfWidth + ", " + halfHeight + ")")
.append("path")
.attr("d","M 0 -80 L 3 0 L -3 0 L 0 -80")
.attr("transform", "rotate(" + calculateHourAngle() + ")")
.attr("class", "hour");
animateHourHand.call(hourHand);
var minuteHand = svg.append("g")
.attr("transform", "translate(" + halfWidth + ", " + halfHeight + ")")
.append("path")
.attr("d","M 0 -100 L 3 0 L -3 0 L 0 -100")
.attr("class", "minute");
animateMinuteHand.call(minuteHand);
var secondHand = svg.append("g")
.attr("transform", "translate(" + halfWidth + ", " + halfHeight + ")")
.append("path")
.attr("d","M 0 -110 L 3 0 L -3 0 L 0 -110")
.attr("class", "second");
animateSecondHand.call(secondHand);
svg.append("g")
.attr("transform", "translate(" + halfWidth + ", " + halfHeight + ")")
.append("circle")
.attr("r", 4)
.attr("class", "knob");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment