Digital clock like in Kyiv Metro, 1970s style. Reference image is provided by Metro Museum.
-
-
Save vsapsai/10750101 to your computer and use it in GitHub Desktop.
Kyiv Metro digital clock.
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
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
background: #111; | |
position: relative; | |
} | |
svg { | |
position: absolute; | |
top: 0; | |
left: 50px; | |
width: 860px; | |
height: 500px; | |
} | |
#underlay { | |
-webkit-filter: blur(2px); | |
-moz-filter: blur(2px); | |
-ms-filter: blur(2px); | |
-o-filter: blur(2px); | |
filter: blur(2px); | |
} | |
#underlay path, | |
#underlay circle { | |
fill: #111; | |
stroke: rgb(20, 20, 20); | |
stroke-opacity: 1; | |
} | |
#underlay .lit { | |
fill: rgb(246, 160, 18); | |
stroke: rgb(226, 112, 17); /* darker blurred stroke */ | |
} | |
/* vsapsai: #overlay path, #overlay circle is empty to make visible blurred underlay */ | |
#overlay .lit { | |
fill: rgb(246, 160, 18); | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var svgUnderlay = d3.select("body").append("svg") | |
.attr({"width": 270, "height": 50, "viewBox": "0 0 270 50"}); | |
var digitWidth = 5, | |
digitHeight = 7, | |
radius = 2, | |
xStep = 7, | |
yStep = xStep; | |
var digitsContainer = svgUnderlay.append("g") | |
.attr("transform", "translate(17, 0)"); | |
appendDigit(digitsContainer, digitWidth, digitHeight, xStep, yStep, radius) | |
.attr("transform", "translate(0, 0)"); | |
appendDigit(digitsContainer, digitWidth, digitHeight, xStep, yStep, radius) | |
.attr("transform", "translate(" + ((digitWidth + 1) * xStep) + ", 0)"); | |
var separatorGroup = digitsContainer.append("g") | |
.attr("class", "separator") | |
.attr("transform", "translate(" + ((2 * digitWidth + 1.5) * xStep) + ", 0)"); | |
separatorGroup.append("circle") | |
.attr({"r": radius, "cx": 0, "cy": yStep * Math.floor(digitHeight / 2)}) | |
.classed("lit", true); | |
separatorGroup.append("circle") | |
.attr({"r": radius, "cx": xStep, "cy": yStep * Math.floor(digitHeight / 2)}) | |
.classed("lit", true); | |
appendDigit(digitsContainer, digitWidth, digitHeight, xStep, yStep, radius) | |
.attr("transform", "translate(" + ((2 * digitWidth + 4) * xStep) + ", 0)"); | |
appendDigit(digitsContainer, digitWidth, digitHeight, xStep, yStep, radius) | |
.attr("transform", "translate(" + ((3 * digitWidth + 5) * xStep) + ", 0)"); | |
var secondsGroup = digitsContainer.append("g") | |
.attr("transform", "translate(" + ((4 * digitWidth + 6.5) * xStep) + ", " + | |
// vsapsai: it's not a reasonable formula, I tweaked it to look good. | |
((digitHeight * yStep - 2 * radius - 1) * 0.3) + "), scale(0.7)"); | |
appendDigit(secondsGroup, digitWidth, digitHeight, xStep, yStep, radius) | |
.attr("transform", "translate(0, 0)"); | |
appendDigit(secondsGroup, digitWidth, digitHeight, xStep, yStep, radius) | |
.attr("transform", "translate(" + ((digitWidth + 1) * xStep) + ", 0)"); | |
var svgOverlay = d3.select("body").append(function() { return svgUnderlay.node().cloneNode(true); }), | |
svg = d3.selectAll("svg"); | |
svgUnderlay.attr("id", "underlay"); | |
svgOverlay.attr("id", "overlay"); | |
var digitPattern = [ | |
[0, 1, 1, 1, 0, // 0 | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0], | |
[0, 0, 1, 0, 0, // 1 | |
0, 1, 1, 0, 0, | |
0, 0, 1, 0, 0, | |
0, 0, 1, 0, 0, | |
0, 0, 1, 0, 0, | |
0, 0, 1, 0, 0, | |
0, 0, 1, 0, 0], | |
[0, 1, 1, 1, 0, // 2 | |
1, 0, 0, 0, 1, | |
0, 0, 0, 0, 1, | |
0, 0, 0, 1, 0, | |
0, 0, 1, 0, 0, | |
0, 1, 0, 0, 0, | |
1, 1, 1, 1, 1], | |
[0, 1, 1, 1, 0, // 3 | |
1, 0, 0, 0, 1, | |
0, 0, 0, 0, 1, | |
0, 0, 1, 1, 0, | |
0, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0], | |
[0, 0, 0, 1, 0, // 4 | |
0, 0, 1, 0, 0, | |
0, 1, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
1, 1, 1, 1, 1, | |
0, 0, 0, 0, 1, | |
0, 0, 0, 0, 1], | |
[1, 1, 1, 1, 1, // 5 | |
1, 0, 0, 0, 0, | |
1, 1, 1, 1, 0, | |
0, 0, 0, 0, 1, | |
0, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0], | |
[0, 1, 1, 1, 0, // 6 | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 0, | |
1, 1, 1, 1, 0, | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0], | |
[1, 1, 1, 1, 1, // 7 | |
0, 0, 0, 0, 1, | |
0, 0, 0, 0, 1, | |
0, 0, 0, 1, 0, | |
0, 0, 1, 0, 0, | |
0, 1, 0, 0, 0, | |
1, 0, 0, 0, 0], | |
[0, 1, 1, 1, 0, // 8 | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0, | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0], | |
[0, 1, 1, 1, 0, // 9 | |
1, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 1, | |
0, 0, 0, 0, 1, | |
1, 0, 0, 0, 1, | |
0, 1, 1, 1, 0] | |
]; | |
var digit = svg.selectAll(".digit"); | |
(function tick() { | |
var now = new Date, | |
hours = now.getHours(), | |
minutes = now.getMinutes(), | |
seconds = now.getSeconds(); | |
digit = digit.data([hours / 10 | 0, hours % 10, | |
minutes / 10 | 0, minutes % 10, | |
seconds / 10 | 0, ((seconds % 10) / 5 | 0) * 5]); | |
digit.each(function(d) { | |
d3.select(this).selectAll("circle") | |
.classed("lit", function(_, i) { return digitPattern[d][i]; }); | |
}); | |
setTimeout(tick, 1000 - now % 1000); | |
})(); | |
function appendDigit(parent, width, height, xStep, yStep, radius) { | |
var digitGroup = parent.append("g") | |
.attr("class", "digit"); | |
for (var y = 0; y < height; y++) { | |
for (var x = 0; x < width; x++) { | |
digitGroup.append("circle") | |
.attr({"r": radius, "cx": x * xStep, "cy": y * yStep}); | |
} | |
} | |
return digitGroup; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment