Skip to content

Instantly share code, notes, and snippets.

@unconed
Created December 11, 2012 22:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unconed/4262856 to your computer and use it in GitHub Desktop.
Save unconed/4262856 to your computer and use it in GitHub Desktop.
MathBox animation vs d3.js enter/exit

MathBox animation vs d3.js enter/exit

In d3.js, data points get turned into individual SVG or DOM elements. When you specify new data, d3 automatically matches up individual points with the previous data, and lets you apply enter/exit effects to points that are new and points that have been removed.

[1, 2, 3, 4] => [2, 3, 4, 5]
enter: [5]
exit: [1]

In MathBox, data points are grouped and drawn as a single batch. When you specify new data, MathBox can't easily separate new points from old, because there is only a single drawing operation per set. Additionally, resizing a vertex buffer requires you to reallocate it, which means you can't animate a primitive efficiently between varying sizes. However, this is generally not a problem in mathematical diagrams, because you tend to set the number of datapoints once at the start, and points typically don't move between sets and have a linear or grid topology.

When you tell mathbox to animate a primitive to a new data set, data points are interpolated indiscriminatedly. So these two animations will have different results:

[1, 2, 3, 4] => [2, 3, 4, 5]
[1, 2, 3, 4] => [5, 2, 3, 4]

e.g.

mathbox.curve({
  n: 4,
  points: true,
  line: false,
  data: [1, 2, 3, 4],
});
mathbox.animate('curve', { data: [2, 3, 4, 5] });

MathBox does have the ability to animate live expressions though, by doing a blind linear interpolation of the results. These animations are equivalent to the previous two on the domain [1, 4]:

function (x) { return x; } => function (x) { return x + 1; } 
function (x) { return x; } => function (x) { if (x == 1) return 5; else return x; } 

e.g.

mathbox.curve({
  n: 4,
  points: true,
  line: false,
  domain: [1, 4],
  expression: function (x) {
    return x;
  },
});
mathbox.animate('curve', {
  expression: function (x) {
    return x == 1 ? 5 : x;
  },
});

This technique is more suited to interpolating between similarly shaped data sets rather than do arbitrary transitions. The idea in MathBox is to realize more complicated transitions by distorting the underlying mathematical space itself. This is done using Viewport objects, for example to perform a cartesian to polar warp. Currently, multiple viewport transforms cannot be combined, but this is easy to add if it becomes necessary.

Alternatively, MathBox primitives can be animated by driving the live expressions off of a clock, and write the entire animation tween yourself, mathematically. The included Director class contains a .clock() method that gives you a clock per presentation slide.

MathBox's equivalent to enter/exit selections is then limited to letting you set a default fade in/fade out transition time, to be applied to entire primitives that are added or removed.

For small data sets, you can still create an individual primitive per data point, but this can be tedious. I haven't explored ways to resize GL buffers quickly for variable size data sets yet. There is also always the possibility of using GLSL attributes to do per data-point animation in the future, but this is likely to take the form of a similar default fade in/out transition rather than custom tweens though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment