A few weeks ago I was looking for a new screensaver for my PC at work. By chance I came across a Polar Clock written by PixelBreaker. This isn’t available from his website anymore, but can be found on several download sights.
I was setting it up when I noticed that it had support for several languages. Being a Gaelic learner and geek I thought I’d try to add Gaelic to the list. It wasn’t possible to add anything to the menu in the Settings, so I just hijacked one of the other language files and changed it all in to Gaelic.
All well and good, but it didn’t get 2, 12 & 20, etc. right due to logic based on counting in 10s, not 20s, and no lenition. Also, as it’s written in Flash, it eats power! A bit more Googling (Ecosiaing actually, but that doesn’t roll off the tongue so easily!) and I came across a Java script version written by Mike Bostock – perfect!
So with a little help from the Scottish Gaelic Grammar Wiki, I set about gaelicising this version. It uses ternary functions and switch statements to trap all the relevant bits of pluralness and lenition, and also uses Diluain (Monday) as the first day of the week.
It is live on my site here and the code is given below. If you want to use it as a screen saver, search for “webpage screen saver” and the name of your OS and you should come up with several options.
<!DOCTYPE html> <meta charset="utf-8"> <style> body { background: #222; margin: auto; width: 960px; } .arc-text { font: 16px sans-serif; } .arc-center { fill: none; } #credit { position: absolute; font: 10px sans-serif; right: 10px; bottom: 10px; color: #ddd; } #credit a { color: inherit; } </style> <div id="credit">Inspired by <a href="http://blog.pixelbreaker.com/polarclock/">pixelbreaker</a>.<br> Adapted by <a href="https://amayze.org.uk">Andy May</a> from <br>code developed by <a href="https://bl.ocks.org/mbostock/1096355">Mike Boston</a>.</div> <script src="//d3js.org/d3.v3.min.js"></script> <script> var width = 960, height = 800, radius = Math.min(width, height) / 1.9, spacing = .09; var formatSecond = function(d) { d = d.getSeconds(); switch ( (3 <= d && d <= 10) || (13 <= d && d <= 19) ? 3 : ((d <= 2) || (d == 12) ? d : 20) ) { case 1: case 11: d += " diog"; break; case 2: case 12: d += " dhiog"; break; case 3: d += " diogan"; break; default: d += " diog"; break; } return d; }, formatMinute = function(d) { d = d.getMinutes(); switch ( (3 <= d && d <= 10) || (13 <= d && d <= 19) ? 3 : ((d <= 2) || (d == 12) ? d : 20) ) { case 1: case 11: d += " mhionaid"; break; case 2: case 12: d += " mhionaid"; break; case 3: d += " mionaidean"; break; default: d += " mionaid"; break; } return d; }, formatHour = function(d) { d = d.getHours(); switch ( (3 <= d && d <= 10) || (13 <= d && d <= 19) ? 3 : ((d <= 2) || (d == 12) ? d : 20) ) { case 1: d = " uair"; break; case 2: case 11: case 12: d += " uair"; break; case 3: d += " uairean"; break; default: d += " uair"; break; } return d; }, formatDay = function(d) { d = d.getDay(); switch ( d ) { case 0: d = "Didòmhnaich"; break; case 1: d = "Diluain"; break; case 2: d = "Dimàirt"; break; case 3: d = "Diciadain"; break; case 4: d = "Diardaoin"; break; case 5: d = "Dihaoine"; break; case 6: d = "Disathairne"; break; default: d = "Latha Eile"; break; } return d; }, formatDate = function(d) { d = d.getDate(); switch (10 <= d && d <= 19 ? 10 : d % 10) { case 1: d += "d"; break; case 2: d += "a"; break; case 3: d += "s"; break; default: d += "mh"; break; } return d; }, formatMonth = function(d) { d = d.getMonth(); switch ( d ) { case 0: d = "Am Faoilleach"; break; case 1: d = "An Gearran"; break; case 2: d = "Am Màrt"; break; case 3: d = "An Giblean"; break; case 4: d = "An Cèitean"; break; case 5: d = "An t-Ògmhios"; break; case 6: d = "An t-Iuchar"; break; case 7: d = "An Lùnastal"; break; case 8: d = "An t-Sultain"; break; case 9: d = "An Dàmhair"; break; case 10: d = "An t-Samhain"; break; case 11: d = "An Dùbhlachd"; break; default: d = "Mìos Eile"; break; } return d; }; var color = d3.scale.linear() .range(["hsl(-180,60%,50%)", "hsl(180,60%,50%)"]) .interpolate(function(a, b) { var i = d3.interpolateString(a, b); return function(t) { return d3.hsl(i(t)); }; }); var arcBody = d3.svg.arc() .startAngle(0) .endAngle(function(d) { return d.value * 2 * Math.PI; }) .innerRadius(function(d) { return d.index * radius; }) .outerRadius(function(d) { return (d.index + spacing) * radius; }) .cornerRadius(6); var arcCenter = d3.svg.arc() .startAngle(0) .endAngle(function(d) { return d.value * 2 * Math.PI; }) .innerRadius(function(d) { return (d.index + spacing / 2) * radius; }) .outerRadius(function(d) { return (d.index + spacing / 2) * radius; }); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var field = svg.selectAll("g") .data(fields) .enter().append("g"); field.append("path") .attr("class", "arc-body"); field.append("path") .attr("id", function(d, i) { return "arc-center-" + i; }) .attr("class", "arc-center"); field.append("text") .attr("dy", ".35em") .attr("dx", ".75em") .style("text-anchor", "start") .append("textPath") .attr("startOffset", "50%") .attr("class", "arc-text") .attr("xlink:href", function(d, i) { return "#arc-center-" + i; }); tick(); d3.select(self.frameElement).style("height", height + "px"); function tick() { if (!document.hidden) field .each(function(d) { this._value = d.value; }) .data(fields) .each(function(d) { d.previousValue = this._value; }) .transition() .ease("elastic") .duration(500) .each(fieldTransition); setTimeout(tick, 1000 - Date.now() % 1000); } function fieldTransition() { var field = d3.select(this).transition(); field.select(".arc-body") .attrTween("d", arcTween(arcBody)) .style("fill", function(d) { return color(d.value); }); field.select(".arc-center") .attrTween("d", arcTween(arcCenter)); field.select(".arc-text") .text(function(d) { return d.text; }); } function arcTween(arc) { return function(d) { var i = d3.interpolateNumber(d.previousValue, d.value); return function(t) { d.value = i(t); return arc(d); }; }; } function fields() { var now = new Date; return [ {index: .7, text: formatSecond(now), value: now.getSeconds() / 60}, {index: .6, text: formatMinute(now), value: now.getMinutes() / 60}, {index: .5, text: formatHour(now), value: now.getHours() / 24}, {index: .3, text: formatDay(now), value: (now.getDay() == 0 ? 6.999 : now.getDay()) / 7}, {index: .2, text: formatDate(now), value: (now.getDate() - 0.001) / (32 - new Date(now.getYear(), now.getMonth(), 32).getDate())}, {index: .1, text: formatMonth(now), value: (now.getMonth() + 0.999) / 12} ]; } </script>
License
Released under the GNU General Public Licence, version 3.