Skip to content

Instantly share code, notes, and snippets.

@alexmasselot
Last active December 29, 2016 06:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexmasselot/c93cd2ba6c4212d4a4a7 to your computer and use it in GitHub Desktop.
Save alexmasselot/c93cd2ba6c4212d4a4a7 to your computer and use it in GitHub Desktop.
CFF clock with d3
var getNow = function(){
var t = new Date();
return {
hours: t.getHours(),
minutes: t.getMinutes(),
seconds: t.getSeconds()
};
};
var getNowArray = function(){
var t = new Date();
return [t.getHours(),t.getMinutes(),t.getSeconds()];
};
<html>
<head>
<title>CFF - d3 clock tutorials</title>
<style>
g.ticks path {
stroke: black;
}
g.ticks g.minute path {
stroke-width: 7;
}
g.ticks g.hour path {
stroke-width: 17;
}
g.hands path {
stroke: black;
}
g.hands g.minutes path {
stroke-width: 1.5;
fill: black
}
g.hands g.hours path {
stroke-width: 1;
fill: black
}
g.hands g.seconds path {
stroke-width: 3.5;
stroke: red;
}
g.hands g.seconds circle {
fill: red;
}
g.hands circle.middle-nail{
fill:#cb7c7a;
}
</style>
</head>
<body>
<div id="target"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.3/lodash.min.js"></script>
<script src="date-commons.js"></script>
<script>
var now = getNow();
//we just print out the date as text in the target element
var svg = d3.select('#target')
.append('svg')
.attr({
width: 500,
height: 500
});
var gMain = svg.append('g').attr({
transform: 'translate(' + 250 + ',' + 250 + ')'
});
var gTicks = gMain.append('g').attr({
class: 'ticks'
});
//transform a angl between 0 and 1 in degree for svg rotation, where 0 is noon
var rotate = function (angle01) {
return 'rotate(' + (angle01 * 360 - 90) + ')';
};
var plotTicks = function (name, number, size) {
gTicks.selectAll('g.tick.' + name)
.data(_.range(number))
.enter()
.append('g')
.attr({
class: 'tick ' + name,
transform: function (t) {
return 'rotate(' + (t / number * 360) + ') translate(' + 230 + ',0)';
}
})
.append('path')
.attr('d', 'm0,0 l-' + size + ',0');
};
plotTicks('minute', 60, 19);
plotTicks('hour', 12, 60);
//time for time
var gHands = gMain
.append('g')
.datum(getNow() )
.attr('class', 'hands');
var gHandHours = gHands.append('g')
.attr('class', 'hours');
gHandHours.append('path')
.attr('d', 'M-54,-15 L-54,15 L152,12.5 L152,-12.5 Z');
var gHandMinutes = gHands.append('g')
.attr('class', 'minutes');
gHandMinutes.append('path')
.attr('d', 'M-54,-12 L-54,12 L222,8.5 L222,-8.5 Z');
var gHandSeconds = gHands.append('g')
.attr('class', 'seconds');
gHandSeconds.append('path')
.attr('d', 'M-84,0 L' + 146 + ',0');
gHandSeconds.append('circle')
.attr({
cx: 150,
cy: 0,
r: 24.5
});
gHands.append('circle')
.attr({
class:'middle-nail',
r:2
});
var isFirstCycle=true;
var nextMinute = function () {
var now = getNow();
if(isFirstCycle){
isFirstCycle=false;
}else{
//after the first cycle, we loose a little amount of time doing the minute hand bounce
//so we need the second hand to start smoothly from 0 and achieve the path in 58 seconds or so
now.seconds=0;
}
gHands.selectAll('g').datum(now);
gHandMinutes.attr('transform', function (t) {
return rotate(t.minutes / 60)
});
gHandHours.attr('transform', function (t) {
return rotate(now.hours / 12 + t.minutes / (60 * 12) + t.seconds / (3600 * 12))
});
var minuteStopMillis = 2000;
var remainMillis = (60 - now.seconds) * 1000 - minuteStopMillis;
gHandSeconds.transition()
.duration(remainMillis)
.ease("linear")
.attrTween('transform', function (d, i, a) {
return function (i) {
var x = d.seconds / 60 + (1 - d.seconds / 60) * i;
return rotate(x);
}
});
gHandMinutes.transition()
.delay(remainMillis + minuteStopMillis)
.ease("bounce")
.duration(500)
.attrTween('transform', function (d, i, a) {
return function (i) {
var x = d.minutes / 60 + (1 / 60) * i;
return rotate(x);
}
})
.each("end", nextMinute);
};
nextMinute();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment