I came across the Flutter Clock contest more than a month after it was announced. It was not much before Christmas and I had a month left, but I like
Flutter so I immediately decided to give it a shot. I quickly had an idea of my creation: when I visited Hungary last summer I visited my good old ex-colleague Miklos Vegh, who is - besides being a CAD software engineer - very proficient in PCB design and electronics. One of his cherished project was a Nixie clock. If you haven’t seen Nixie Tubes: they illuminate digits and some symbols placed inside a tiny glass tube. See this website. If you Google “Nixie Tube clock kit” you can see low and high price versions of various designs.
I love the aesthetics of
Nixie Tube clocks so my choice was to bring that experience to the Flutter Clock contest. The library provided by the contest also provides extra information such as weather and temperature. I had an idea to have a bottom portion of the clock where I’d display this information in a style of Vacuum Fluorescent Displays.
VFD is older technology than
LCD displays, so in my mind I still preserve some retro feeling. This certainly could have be a choice if I’d target a Nixie Tube steampunk route, but that’s not the direction of the design.
I started to study Nixie tubes and think how could I synthetize the visuals. One distinctive feature is the shape of the digits. I could either draw the digits, but it could be a simpler solution to find a font which closely resemble Nixie Tubes. The font definitely has to be Sans Serif and very thin along with specific features of various digits. This Design Stackoverflow topic has a lot of very good choices. I even purchased
TTChocolates for mobile app distribution, but in my submission I use thin weight version of Roboto Mono. That’s a Google Web Font, so the judges can potentially use it more freely for their own purposes (I’d be so happy to see this as a clock choice in some app). The Roboto Mono’s zero digit has an unwanted crossover and the digit 1 has the cap, but I think overall it’s still curved fine and thin enough. It’s 95% close to what I want (TTChocolates would be 100%). The fact that it’s monospaced can help a lot with the sizing and position of the tubes.
The bottom portion also uses a Google Web Font: a VT 323. That is also a monospace font and its pixelated design gives a very nice retro feeling. I only had to add some background pattern and a foreground grid which would represent the VFD control grid. Normally that’s a hexagonal grid just like what someone would see in (most of of the) Nixie Tubes, but for simplicity I went with a rectangular grid here. The hexagonal grid would have been too small: it could not have been generated with satisfiable or visible aesthetics.
I highly modularized all Widgets into sub widgets taking full advantage of Flutter’s principles. While other UI frameworks discourage using too complex or deep widget hierarchy, Flutter’s internal algorithms are linear - O(1) algorithmically - which allows composition of many widgets without significant performance impact. This way Widgets can be lean and focus only on their specific task. Separation of responsibility is awesome!
The VFD Widget for example is composed of 3 VFD Lines, each of which are composed of individual VFD characters. The lines could have been
Text() widgets of the whole line strings, but then I’d need to paint the whole foreground and the background in one run: towards the end of the line this caused offset artifacts in the delicate patterns compared to the monospace font. When each character has its own small foreground and background painter I can avoid the gradual increasing offset problem and several calculations. There’s also a trick that I can reuse the same painter for background and foreground painting: the hairlines of the two needs to perfectly align anyway, so we might as well use the exact same code and comply with the DRY principle as well.
The Nixie widget part of the clock is composed of 8 separate Nixie Tube widgets. The tubes have background and foreground painters which are responsible to draw the tube outline, the legs of the tube, the internal hexagonal grid and some internal details like the hanger rings. The digits are exactly lined up in order as in a real nixie tube. I had to make one distinction though: I was able to light up the given digit in that order but the visuals weren’t satisfying. So the widget always takes out the active digit from that order and brings it up front right behind the hexagonal grid but above all the inactive digits. This decreases the emulation’s reality but increases contrast and helps readability.
On the high level I’m using InheritedWidget pattern to deliver the extra information to the desired widgets within the widget tree. For more details please check out the full GitHub repository: GitHub Repository. Also check out this live demo. This clock doesn’t look as good on
Firefox by the way, but let’s not forget that web platform of Flutter is still in beta and under development. So I’d advise to view the live demo with
Chrome right now. Overall
Flutter in itself is a new technology and I’m extremely happy that we’ll have something which can target
web with the same codebase. Last time I saw such technology was the
PlayN framework, which was a Google backed technology as well, and this is why our mobile game has on-line demo. In the future I want to rewrite
Deal-O-Round in Flutter.
As far as Flutter Clock goes I also thought to create some fun animated clock along the lines of the Google I/O 2018 digit animations. I have a concept and maybe I’ll implement that because I’d like to learn more about Flutter animations. Stay tuned for follow-up posts and please cheer me for a placement in the Flutter Clock contest.