Reticle Designer
Part 3: SVG, Flexbox, React, and MobX
This article is the last in a three-part series where each article reflects on its corresponding sandbox goal mentioned in the Intro section below.
- Part 1: Deconstructing the Design
- Part 2: Subtle Gamification
- Part 3: SVG, Flexbox, React, and MobX
Intro
I wanted to design and develop a creative authoring tool for quickly making FUI reticle designs. Additionally, I wanted it to double as a sandbox for:
- experimenting with custom UI controls and UX microinteractions
- employing ideas from Daniel Cook's Mixing Games and Applications
- practicing the use of SVG, Flexbox, React, and MobX
Reticle Designer is that creative authoring tool and sandbox. Those interested in HTML, CSS, and JavaScript will likely find the details below interesting. Before jumping into those however, here are a few examples of what can be built with Reticle Designer:
If you didn't already know, a reticle is a pattern of fine lines or markings built into the eyepiece of a sighting device (think telescopes, microscopes, and gunsights). Most of what I create are exaggerated and creative versions. If you watch or play futuristic science fiction movies and games you'll notice they often have similar reticles in their gunsights, HUDs, UIs, and dashboards.
You can launch the app prior to reading on to test your personal experience against the ideas of this article.
SVG
Reticle Designer's UI can be divided into two core parts:
- SVG canvas
- HTML Edit Panel overlay
The SVG canvas (not to be confused with <canvas>
) ends up being a DOM tree of <circle>
s, a custom drawn <path>
(arc), or SVG's <use>
duplicated and evenly distributed along a circle (via JavaScript trigonometry). The distinction is made based on unique combinations of the Edit Panel's Divisions, Spacing, and Graphic settings. SVG in combination with React and MobX are a killer combo which enable the SVG canvas DOM (in JSX) to look as simple as:
{this.props.stores.reticlesStore.items.map(item =>
<Reticle key={item.id} item={item}>
)}
The custom <Reticle>
React component abstracts away the three visual variations previously mentioned based on Edit Panel settings. In my previous experience with both Angular 1 and 2, using SVG was always a PIA. SVG with React and the syncing UI render power of MobX is a much nicer experience.
Graphics Library
Regarding the SVG element <use>
, I had previously not used it much. It is a super valuable SVG element however. Essentially it enables SVG templating and was a killer combo with what I wanted to accomplish in Reticle Designer. Here's a screen shot showcasing it's output:
Example SVG <use>
via Divisions 15 setting
From an implementation perspective, I created a custom <GraphicsLibrary>
React component which contained a one-time definition of 60+ custom SVGs. Some JavaScript trigonometry with SVG's <use>
is a killer combo that enabled the SVG canvas to take shape. Additionally, the Edit Panel's ability to accurately reflect the SVG definition in focus is reflected in the Graphic Edit Panel setting above. Lastly, the reuse of <use>
is again reflected in the Graphics submenu demonstrated below:
Example SVG <use>
in Graphics submenu
Node.js
Another interesting note is that most of the 60+ Graphics are actually HTML entities manipulated and exported as SVG from Adobe XD (though any SVG export tool could have worked). Since learning about Node.js local use cases over time, I knew I could (and did) create a script that:
- Parsed all the XD output SVG files
- Extracted SVG code of each file
- Removed extraneous code
- Injected specific hooks for use in Reticle Designer
- Merged them into a single usable output
You can actually view, take, and customize the svg-graphics-library-formatter.js GitHub Gist for any personal, commercial, or non-commercial use regarding the parsing of many SVG files at once. This solution's output (which could be further optimized for DX, automation, or any other goal) worked like a charm. At its core, it enabled a seamless workflow by bridging manual design-centric edits in Adobe XD with easily consumable <GraphicsLibrary>
updates in Reticle Designer. For example I can easily create new graphic in Adobe XD, save it as a .svg, and then run the script so Reticle Designer can automatically provide the new graphic in the app.
Flexbox
Flexbox is awesome, but it's API sucks. It is very unintuitive and more complex than it needs to be. I considered leveraging a build tool process where a redefined API would translate to valid Flexbox upon a build. This would have added more complexity for the tradeoff of a friendlier and more intuitive API. If I had it my way, the API would change:
- from
justify-content
toflex-distribution-main
- from
align-items
toflex-distribution-cross
I made a Flexbox Cheatsheet to help alleviate the pain for those interested. Maybe someday I'll implement tooling for better DX when authoring Flexbox CSS.
React
Prior to using React I had used both Angular 1 and 2 and I enjoy authoring in both. Each, like React, empower client (UI/UX/interactive/frontend/etc. take your pick) developers with two core abilities:
- to define custom elements declaratively
- to leverage a data binding mechanism for syncing UI and models
These two factors enable faster authoring times, reliable reuse of simple and complex custom components alike, and useful abstractions for keeping data and your app's UI up-to-date. I used to be a bigger fan of Angular, but since using React my gut feeling of both Angular versions feeling over engineered was confirmed.
React has a much simpler API and mental model, but more importantly it is more performant (with a lighter footprint) due to its architectural approach. Combined React is better than Angular IMHO. Going another step and using the state management library MobX with React further empowers client developers.
MobX
In my ~10 year career thus far I've been in pursuit of an eventing mechanism or strategy that improves developing rich frontend applications. I always had a feeling that there was a better way, I just didn't know what it was. The pursuit started with Signals.as
in Actionscript 3 with Flash and its port to JavaScript by Miller Medeiros. Both were a step up from the inherent bubbling eventing systems. In C# I've used Action
s and then came data binding libraries in JavaScript. Each were variations or improvements that better enabled rich frontend applications to be authored and synchronized. MobX is the best I've found to date.
MobX is a state management library that kicks ass for three core reasons:
- MobX abstracts away the otherwise explicit eventing and observing of changes in an app's runtime lifecycle
- Deep internal understanding of the state-tree enables selective and efficient UI re-renders
- minimal API so it is simple to understand, memorize, and implement
Two mental models that MobX promotes are:
- An app's UI is a function of its state (UI = fn(state), functional programmers rejoice)
- Core state should be minimal, you're encouraged to think in terms of derived state (which MobX can further optimize)
All this means that you can use a tiny API in conjunction with traditional mutations and callbacks to automatically wire up efficient change tracking and subsequent observervable side-effects (like snappy UI updates). You can find more details in my notes from the book MobX Quick Start Guide by Pavan Podila & Michel Weststrate (Michel is the author of MobX).
Conclusion
All in all, my experiement in creating Reticle Designer was a success. I made a cool creative authoring tool and additionally got to explore the sandbox goals that were more deeply covered as part of this three part series. Hope you enjoyed reading.
If you have any thoughts, don't hesitate to reach out @derekknox.