Drawing with GFX

dojox.gfx

 

What is it?

dojox.gfx is a cross-platform declarative interactive graphics package. It follows SVG loosely as the underlying model. At present time SVG and VML back-ends are implemented.

What does it do?

The dojox.gfx package provides graphics rendering and manipulation. Under Firefox, Opera and Safari dojox.gfx renders the final product as SVG, under IE it renders as VML.

Potentially the gfx package can allow you to create live and interactive graphing, a web based vector drawing program, view svg files in IE.

Underlying concepts

On conceptual level dojo.gfx has a simple declarative model: All basic primitives required for 2D graphics are defined:

  • 2D coordinates
  • 2D linear transformation matrices
  • colors

There is a surface, which serves as a visual rectangular container for shapes:

  • A web page can have several surfaces defined.
  • Each surface has its own local coordinate system:
    • (0, 0) point is in the left-top corner, where the X axis is horizontal pointing right, and the Y axis is vertical pointing down.
    • Positive direction of rotation is defined as counter-clockwise (CCW).

There is a notion of a shape description object, which represent a simple description of geometry, with corresponding shape objects. dojox.gfx supports following shapes:

  • Rectangle (optionally with rounded corners).
  • Circle.
  • Ellipse.
  • Line.
  • Polyline/polygon.
  • Path (the most versatile shape). It implements the full SVG path language.
  • Image.
  • Text.
  • TextPath (highly experimental at the moment).

Shapes support following set of properties:

  • Geometric properties:
    • Shape description (shape-specific).
    • Linear transformation specified by 3 x 3 2D matrix.
    • Font (only for text shapes).
  • Visual properties (not supported by the image shape):
    • Stroke (outline of a shape).
    • Fill (interior of a shape).

Shapes are stacked from bottom to top in an order of their definition. This z-order can be changed dynamically.

There is a group, which is a pseudo-shape. It combines other shapes (and possibly groups), and can be used to apply transformation to a group. All group members share a single z-order, but can be re-arranged within a group.

In order to draw a picture a programmer constructs a pseudo-DOM from a surface object, shapes, and groups, sets appropriate attributes, and picture is drawn automatically by a browser. Modifications of shapes change picture automatically. It is possible to attach event handlers to shapes using dojo.event.connect(). Following conventions are used:

While a path is the most universal geometric shape, which can emulate almost all other shapes (exceptions: image, and text shapes), all frequently-used shapes are provided as a convenience: rectangle (with optionally rounded corners), circle, ellipse, line, polyline/polygon.

All shape description properties are defined using a duck-typing technique. Incomplete shape description definitions are supported. All missing members will be taken from corresponding default shape definitions listed in common.js or from the current shape description object. Example: rect.setShape({width: 200}) - all missing members will be taken from dojo.gfx.defaultRect object making it equivalent to rect.setShape({x: 0, y: 0, width: 200, height: 100, r: 0}).

All shape description objects and visual property objects have a member called "type", which uniquely identifies a property type. This is a provision for a possible serialization.

Certain shape properties can be defined using shortcuts:

  • Path can be defined as a string of path commands (more on path later):
    • path.setShape("m 0,0 l 100, 100 e") is equivalent to path.setShape({path: "m 0,0 l 100, 100 e"}).
  • Polylines/polygons can be defined as an array of points:
    • poly.setShape([{x: 0, y: 0}, {x: 100, y: 100}]) is equivalent to poly.setShape({points: [{x: 0, y: 0}, {x: 100, y: 100}]}).
  • Stroke can be defined by specifying a color as a string:
    • shape.setStroke("black") is equivalent to shape.setStroke({color: "black"}).

All methods without an apparent return type return their object itself. It is used for chaining multiple operations:

  • surface.createRect({x: 100, y: 50}).setFill("red").setStroke("blue");