EaselJS Line Decorator
One of the interesting features of the Flex Freehand Drawing Library was a rich set of line decorators. These modules worked in tandem with a drawing engine to allow a wide variety of geometric objects to be drawn from a small code base. For example, a two-point drawing engine could display anything from a straight line between the two points to a geometric shape defined by the bounding box of the points to a smooth curve using the two points as endpoints (and an arbitrary third parameter). Lines or curves could be drawn with dashes, dots, or even sprites distributed along a path simply by changing line decorators.
A line decorator applies the Decorator pattern to a drawing API for a particular environment. For EaselJS or any canvas-based engine that supports clear(), moveTo(), lineTo(), and curveTo(), a line decorator may be applied in lieu to straight calls to methods of the graphic context. A reference to the context is passed to the decorator to allow it to be applied to more than one canvas drawing engine.
For example, consider the sequence of calls
Suppose the variable, lineDecorator, is a reference to a line decorator (currently separate from the CompGeoJS source, but easily accessible from this site). Instead of making direct calls to the graphic context, use the following code
lineDecorator.moveTo(g, 10, 10);
lineDecorator.lineTo(g, 100, 100);
Now, if you wish to replace solid-line drawing with dashed lines, simply replace the lineDecorator reference with a dashed-line decorator and no actual drawing code needs to be modified.
I will develop and distribute a small set of line decorators through this site (you can view source to pick up the appropriate non-minified JS). These decorators work with an EaselJS context but could work with any other canvas engine that supports a compatible drawing API. For quadratic arcs, proper arc-length parameterization is required to decorate the render so all decorators available from this site will have a dependency on a quad. Bezier from CompGeoJS. Since I expect them to be used for rendering applications in which CompGeoJS is deployed, this should not be an issue. The reason for the dependency is to avoid redundant computations in both the CompGeoJS quad. Bezier and line decorator codes.
Line decorators also expose a setParams() method, which is useful for assigning arbitrary name-value data to the decorator, such as dash-width and dash-spacing for a dashed-line decorator. The generality of the interface allows a wide variety of line decorators to be coded and used to vary the way in which geometric objects are drawn without changing any underlying drawing code. You could draw arbitrary polygons, for example, with solid, dashed, and dotted lines – even at random – simply by switching the decorators applied to the graphic context. Make it even more interesting by randomly varying the decorator applied to each side of the polygon!
To illustrate the process, I have examples of solid- and dashed-line decorators that implement everything except curveTo() for the dashed case (as I do not yet have the quad. Bezier in CompGeoJS). You can see these in action in the line decorator demo. This demo is based on the CompGeoJS parametric line except that line decorators and properties may be interactively changed.
I will update the demo in the near future when the dashed-line decorator fully supports curveTo(). In the mean time, view the source to see how the basic drawing code is implemented and how the Decorator is applied.