Skip to content

Instantly share code, notes, and snippets.

@nacmonad
Last active December 9, 2015 23:24
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 nacmonad/49f270e101e02d1c8203 to your computer and use it in GitHub Desktop.
Save nacmonad/49f270e101e02d1c8203 to your computer and use it in GitHub Desktop.
Simple D3 Clock using Arcs & arcTween transitions
<style type="text/css">
svg {
background:#363636 ;
}
.second-tick{
stroke:chartreuse;
stroke-linecap:round;
stroke-width:2.5px;
}
#seconds {
fill-rule: evenodd;
fill: #aaa;
stroke: chartreuse;
stroke-linejoin:round;
stroke-width: 2.5px;
}
#minutes {
fill-rule: evenodd;
fill: #aaa;
stroke: chartreuse;
stroke-linejoin:round;
stroke-width: 5px;
}
#hours {
fill-rule: evenodd;
fill: #aaa;
stroke: chartreuse;
stroke-linejoin:round;
stroke-width: 10px;
}
</style>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.2"></script>
<script type="text/javascript">
var r = 200,
m = 25;
var w = (r+m)*2,
h = (r+m)*2;
var secondTickStart = r;
secondTickLength = -15;
var secondScale = d3.scale.linear()
.range([0,354])
.domain([0,59]);
var fields = [
{name: "hours", value: 0, size: 12},
{name: "minutes", value: 0, size: 60},
{name: "seconds", value: 0, size: 60}
];
var arc = d3.svg.arc()
.innerRadius(0.25*r)
.outerRadius(function(d) {
if(d.name == "hours") {return 0.8*r } return r})
.startAngle(function(d) { return (d.value / d.size) * 2 * Math.PI; })
.endAngle(function(d) { return (d.value / d.size) * 2 * Math.PI; });
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
var dynamics = svg.append("g")
.attr("class", "dynamics")
.attr("transform", "translate("+(r+m)+"," + (r+m) + ")");
var statics = svg.append("g")
.attr("class","statics")
.attr("transform", "translate("+(r+m)+"," + (r+m) + ")");
//add marks for seconds
statics.selectAll('.second-tick')
.data(d3.range(0,60)).enter()
.append('line')
.attr('class', 'second-tick')
.attr('id', function(d){return d})
.attr('x1',0)
.attr('x2',0)
.attr('y1',secondTickStart)
.attr('y2', secondTickStart + secondTickLength)
.style('stroke-width', function(d) {
if( d%5==0 ) { return '10px'}
return '2.5px'
})
.attr('transform',function(d){
return 'rotate(' + secondScale(d) + ')';
});
setInterval(function() {
var now = new Date();
fields[0].previous = fields[0].value; fields[0].value = now.getHours()+now.getMinutes()/60+now.getSeconds()/3600;//continuously moving hour hand rather than snapping
fields[1].previous = fields[1].value; fields[1].value = now.getMinutes();
fields[2].previous = fields[2].value; fields[2].value = now.getSeconds();
var path = dynamics.selectAll("path")
.data(fields.filter(function(d) { return d.value; }), function(d) { return d.name; })
.attr("id", function(d){return d.name;});
path.enter().append("path")
.transition()
.ease("elastic")
.duration(750)
.attrTween("d", arcTween);
path.transition()
.ease("elastic")
.duration(750)
.attrTween("d", arcTween);
path.exit().transition()
.ease("bounce")
.duration(750)
.attrTween("d", arcTweenEnd);
//.remove(); //how to redraw at 0 position immediately after...
}, 1000);
function arcTween(b) {
var i = d3.interpolate({value: b.previous}, b);
return function(t) {
return arc(i(t));
};
}
function arcTweenEnd(b) {
if(b.name == 'seconds' && b.value==0) {b.value=60};
var i = d3.interpolate({value: b.previous}, b);
b.value=0;
return function(t) {
return arc(i(t));
};
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment