Last active
December 29, 2016 06:42
-
-
Save alexmasselot/c93cd2ba6c4212d4a4a7 to your computer and use it in GitHub Desktop.
CFF clock with d3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()]; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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