The OpenLaszlo application below demonstrates animation along a line, a quadratic Bezier, and a cubic Bezier (the top three paths). It also demonstrates (the bottom path) animation along a path composed of multiple segments.

Drag the slider back and forth to display the point on each path at t=slider.value/100, or click the “Animate” button to animate t from 0 to 1.

I wrote this in order to animate the state markers along the edges of the graph in reAnimator. The GraphViz dot tool, which I’m using for graph layout, generates cubic beziers, so I had to write code to render and evaluate them.

If you’re writing for FireFox a browser that supports the canvas element, you can use the same code with the new HTML canvas element. Click on “Start Animation” to animate the points on the canvas below. And click here to open the HTML applet in its own window.

Files:

  • bezier.js — measurement, interpolation, sampling, and subdivision for arbitrary-order Beziers

  • path.js — measurement, interpolation, and sampling for paths composed of multiple lines and Beziers

  • bezier-demo.js — the code to draw the paths in the demo. This is platform-agnostic, and works in OpenLaszlo (bezier-demo.lzx) and HTML (bezier-demo.html).

  • bezier-demo.lzx — the OpenLaszlo demo

  • bezier-demo.html — the HTML demo

  • drawview-patches.js — patches to the OpenLaszlo LzDrawView. This includes an implementation of LzDrawView.bezierCurveTo.

A couple of caveats:

  • This animates along the Bezier parameterization, not the path length. This was good enough for my application, but you could get animation that speeds up and slows down, depending on how you choose your control points.

  • The demo code is written for brevity, not speed. In particular, it re-renders the background each time, which involves some expensive math to render the cubic. In reAnimator, I placed the animated elements on a separate view in front of the background. I didn't do that here because I wanted to share code between the OpenLaszlo and HTML demos, and the techniques for doing overlays were too different.

    Using a separate overlay for the background didn’t actually speed this up. The hot spot is the parametric position calculation.


Update: The inline examples weren’t showing up. Thanks to Bret Victor for both finding and diagnosing the problem. (I was linking to my laptop, osteele.dev. The post looked fine from my laptop!)