Animated Markers on an SVG Map

I recently started my new job at Headnote. My first project was to redo all of the public facing pages to update the branding and advertising language. The one piece of code I would like to share from the experience is the animated markers that pop up in various places on a map. Now, I am new to Less (purely a Sass guy before this gig), so this was a great learning experience for me about what advanced features Less supports compared to Sass. There were definitely some challenges. The main one being that Less is much less flexible (no pun intended) in terms of interpolation and apparently is very very picky about using variables / interpolation on the left side of a definition (I dont know what else to call it)… For example:

1
2
3
4
5
@side: left;

.my-class {
  margin-@{side}: 5px;
}

This particular example works… however when I tried to use this sort of interpolation for keyframe animation, Less complained endlessly. Admittedly this is a bit of an edge case. I tried every possible combination of escaping, string concatenation, interpolation, etc and could get neither the % sign needed for defining keyframes nor inline math to work. In my experience, Sass is a bit more forgiving in this regard, although I havent tried re-creating this exact code in Sass.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.map-keyframe-set(@base-percent, @offset) {
  @{base-percent}% { // syntax error!
    opacity: 0;
  }
  (@{base-percent})% { // syntax error!
    opacity: 0;
  }
  @{base-percent}\% { // escaping doesnt work!
    opacity: 0;
  }
  @{base-percent}~"%" { // this escaping doesnt work either!
    opacity: 0;
  }
  "@{base-percent}%" { // Nope!
    opacity: 0;
  }
  @{base-percent} + @{offset} { // math doesnt work!
    opacity: 0;
  }
  (@{base-percent} + @{offset}) { // math doesnt work!
    opacity: 0;
  }
  //...
}

Believe me, these are not all the syntaxes I tried. I spent almost an hour being stubborn about this… I ended up going with a simple but extremely un-satisfying solution. Pass values in as percentages and do the percentage math first, then use the resulting value in the definition.

1
2
3
4
5
6
7
8
.map-keyframe-set(@base-percent, @offset) {
  @start: (@base-percent + @offset);

  @{start} { // OK!
    opacity: 0;
  }
  //...
}

Anyways, here is the result! PLEASE open this in a new tab, you cannot see the whole map in this tiny iframe

See the Pen KmLeXd by Skylar Brown (@skylarmb) on CodePen.