Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Diff transforms

transform_diff(m, target) turns text m into text target by diffing their tokens with Myers’ diff. Unchanged tokens stay put or slide, moved tokens travel on an arc, and only real changes fade or morph. It works on any text: text, math_tex, latex and code.

let eq = scene.add(math_tex("a^2 + b^2 = c^2").scale(1.5));
scene.play(write(eq));
scene.play(transform_diff(eq, math_tex("a^2 = c^2 - b^2").scale(1.5)).run_time(1.5));

After the transform, m holds the new text, so it can be diffed again.

Code diffs line by line, then token by token within changed lines:

let src = scene.add(code(BEFORE, "rust"));
scene.play(transform_diff(src, code(AFTER, "rust")).run_time(2.0));

Options

A third argument, a map, tunes the choreography:

scene.play(transform_diff(eq, math_tex("a = sqrt(c^2 - b^2)"), #{ highlight_changes: true }));
OptionTypeDefaultEffect
highlight_changesboolfalseFlash the tokens that changed
lag_ratiofloat0.05Stagger between token moves
move_arcfloatPI / 3Arc angle of moved tokens, in radians
debugboolfalseTint tokens by how they were matched

Lists

transform_list(m, target) diffs two lists cell by cell. Two cells that swap places trade with a pair of arcing moves, which makes sorting algorithms easy to show:

let xs = scene.add(list([3, 1, 2]));
scene.play(transform_list(xs, list([1, 3, 2])));
scene.play(transform_list(xs, list([1, 2, 3])));