Code.Movie

Blog / Improved animation heuristics in 0.0.31

The Code.Movie core library has been upgraded with substantially improved animation heuristics, support for the range syntax in CSS media queries and a new minCols output option. Code.Movie is a JavaScript library that animates source code for the web - imagine a combination of git diffs, virtual DOM diffing, syntax highlighting, code annotations and CSS animations.

1234
[,]"World""Hello"
➡️🚫
[]
["World"]
["Hello", "World"]
[
  "Hello",
  "World"
]
[
  "World",
  "Hello"
]

Improved heuristics

Code.Movie's core algorithm is a slightly odd tree-level diffing algorithm that, unlike most such algorithms, optimizes for the lowest possible visual disruptiveness of the animation. It works by first using Lezer to parse the input code into a regular parse tree and then extensively “massaging” the tree. This last stage consists of several sub-stages:

  • Tokens like 42.23 or "Hello" get split (e.g., into 42, . and 23 or ", Hello and ") to make morphing numbers, strings, comments, and the like possible. This must be implemented on a per-language level.
  • Major language constructs like classes and functions get fingerprinted. The fingerprints (or chains thereof) then serve to weakly “glue” nested language constructs to their parents. This obviously also needs to happen for each language in a slightly different way.

The above is a lot of work but makes sense for what's almost a semantic diffing algorithm. But Code.Movie is only almost a semantic diffing algorithm and ignoring the visual aspect has previously lead to the heuristics taking some quite jarring leaps - a problem that's much reduced in version 0.0.31:

From a fingerprinting perspective, all three calls to the foo() function in the above example are identical, so the } tokens don't feel particularly glued to any of the three calls. On the other hand, they do feel glued to the numbers 111, 222 and 333 that they had previously had as neighbors… and thus decide to move across lines in a way that does not really make sense visually.

Code.Movie 0.0.31 adds a positional fingerprint to major language constructs as well as to structures that are not really “language constructs” (such as lines, sequences of lines, blocks, indentation levels). This process works the same for every supported programming language and therefore improves animation heuristics across the board! The resulting performance impact is barely measurable.

Other changes