I was working on a project recently where I needed to animate an SVG seven segment display. I thought that this would be a great place to use CSS animation
and @keyframes
but there would be a lot of repetition in the CSS so I scripted it with Sass.
I’ve put together a Sassmeister example (click on the “Result” tab to see it in action):
Play with this gist on SassMeister.
This will only work in IE10+ and modern Chrome, Safari, Firefox.
Elements of Note
There are some specific elements of the solution that I wanted to call out.
Segment Animation Mixin
[gist id=”eafd9e4c18368fdab02c” file=”seg-animation.scss”]
This is the meat of the solution. I am using iteration and calculation to build the @keyframes
for the animation. This mixin is called once for each of the seven segments.
Line 1: First, I figure out how big each “slice” of the animation will be ($seg__slice
).
Line 6: Then, I iterate from 1 (assuming the animation starts at 1) through the target number.
Line 7: For each iteration I output what the keyframe percent should be for the given target number.
Lines 8-9: I save the $seg__opacity
in a variable rather than outputting directly because I want to ensure that I end at the last state on Line 13.
Segment Opacity Function
[gist id=”eafd9e4c18368fdab02c” file=”seg_opacity.scss”]
Since I’m just dealing with turning opacity
on and off, I used a bit mask to make the logic easier.
Each element in the $seg_mask
map represents a segment in the display and each element in the list value
represents the state for a particular digit.
Seven Segment SVG
[gist id=”eafd9e4c18368fdab02c” file=”SassMeister-rendered.html”]
In my first attempt at this, I was changing the SVG fill color in the animation – but I realized that it would be more efficient to manipulate opacity. With this in mind, I updated the SVG to have two sets of segments – on and off. The “off” segments will always be the grey color and the “on” segments will always be the red color. In the animation I simply change the opacity of the “on” segments.
Main Sass
[gist id=”eafd9e4c18368fdab02c” file=”main.scss”]
This is what actually outputs the CSS – everything else is mixins or functions.
Lines 1-9: I used an extend for the default state so that it was shorter in the CSS.
Line 11: The animating
class is there to facilitate starting/stopping the animation via JavaScript by simply adding or removing that class.
Line 12: I created the seg_list()
function to avoid having to repeat my segment names (tr, br, b, bl, tl, t, m).
Line 14: I used the step-end
transition because I wanted a hard change from one state to another, not a gradual fade.