Cango Graphics User Guide
Introduction
Cango (CANvas Graphics Object) is a JavaScript library designed to assist drawing on the HTML canvas element. The core module supplies the Cango object whose methods handle world coordinates, layers, and all rendering onto the canvas. It also supplies the basic drawing objects: Path, Shape, Img, Text and ClipMask that can be easily styled and transformed, once created these objects can be rendered using any Cango context. The Cango User Guide provides a detailed reference for the objects and their and methods along with the Cango core methods and properties.
Cango is open source and the current version is available for download at Cango-33v08.js.
Several extension modules are available to give enhanced capabilities for Animation, Graph Axes, Text manipulation, Zoom-and-Pan and so on.
Cango basic drawing capability
Figure 1. Examples of drawing using the Cango graphics library.
Features of Cango
- User defined World Coordinates - Cango supports independent X and Y scaling. Data may to be plotted in its original units removing the need to scale all values to canvas pixels. Each Cango instance can have its own world coordinates. Multiple Cango graphics contexts may exist together on a single canvas.
- Right Handed Cartesian (RHC) and SVG style (Left Handed Cartesian) coordinate systems support - Cango supports both RHC coordinates which have Y values increasing UP the canvas, and SVG coordinates which have Y values increase DOWN the canvas. Since each Cango context instance has its own world coordinates, the different coordinate systems may co-exist on a canvas.
- Canvas Layers - The functionality of a CanvasStack is built into Cango. Transparent canvas overlays can be created to assist in drawing cursors, data overlays and animation without re-drawing any static objects on the background canvas or other layers.
- Objects - Cango exports five core drawing objects; Path, Shape, Img, Text and ClipMask. These are the building blocks of all the drawing done by the Cango library.
- Groups and inherited transforms - Cango exports the Group object which enables multiple drawing objects to be handled as a single entity. Groups can have more Groups as children, creating a family tree of objects. Group methods enable transforms to apply to to all children of the Group in a single call. Child objects inherit the transforms applied to parent Groups.
- PathSVG - Cango uses the PathSVG object to create and manipulate SVG path data. These can then act as the descriptor for Path, Shape or ClipMask objects. The PathSVG object behaves similarly to the Path2D canvas utility but with different, somewhat more useful methods. Its static methods supply lots of predefined shapes; circle, square, ellipse etc. along with making paths to fit arrays of data points.
- Pointer events - All drawings objects can be enabled for mouse click and drag-n-drop events. Groups can also, which arms all child drawing objects to respond to event. All the event handling support code is built-in, applications just specify the callback function.
-
Color Gradients, Drop Shadows and Borders - Cango objects can have border and shadows with a variety of styles and colors.
Getting Started
To use the Cango, download Cango-33v08.js, save the file on your server then add the following line to the web page header:
<script src="Cango-33v08.js"></script>
Within the body of the web page insert a canvas element. The only attribute required by Cango is a unique id string. Cango drawing starts by creating a Cango object, the constructor's only parameter is the ID of the canvas.
const cgo = new Cango(canvasID);
Setup the world coordinate system
Cango uses the viewport to provide a reference for the world coordinate origin and the X and Y scale factors. By default the viewport covers the full canvas. The viewport dimensions can be redefined by the viewportPadding method.
The world coordinates are defined by calling either of two methods:
cgo.setWorldCoordsRHC(Xorigin, Yorigin, Xspan, Yspan); cgo.setWorldCoordsSVG(Xorigin, Yorigin, Xspan, Yspan);
These methods set up a Right Hand Cartesian system, a standard for math and science graphics, or left hand cartesian, the coordinates used in SVG or raw canvas drawing. The parameters defined the world coordinates of the canvas. The setWorldCoordinateRHC parameters refer to the world coordinate values of the bottom, left corner viewport and its width and height. The setWorldCoordinateSVG parameters refer to the world coordinate values of the top, left corner viewport and its width and height.
Simple drawing
Cango can draw paths, shapes, images and text. The simplest way to do this is using any of the Cango methods:
cgo.drawPath(pathDef, options); cgo.drawShape(outlineDef, options); cgo.drawImg(imgDef, options); cgo.drawText(strg, options);
Each of these methods creates an instance of the corresponding Path, Shape, Img or Text object and renders it to the canvas. The 'options' object properties are used to apply transforms to the descriptor coordinates to translate the object's coordinates, or to scale, rotate or flip it. These properties can also set style properties such as color, line width, borders, drop shadows etc.
Path and Shape objects take SVG 'path' data syntax to define line or shape outline to be drawn. The SVG data can be in a string or array.
Graphing 2D data is made very simple using the Path object. If the Path descriptor is just an array of number, the Path object will insert an initial 'M' command so that the data array becomes valid SVG syntax. So to plot the data first set the world coordinates to suit the range of x values and y values, create a Path with the array as its descriptor and render the Path or simply use 'drawPath' to do that it in a single call. As an example, Fig 3 shows a graph of a sine wave of amplitude 50 over the range 0 to 2π.
Figure 3. Graph plotting using 'drawPath'.
function plotSine(cvsID)
{
const g = new Cango(cvsID);
g.viewportPadding(10);
g.setWorldCoordsRHC(0, -50, 6, 100);
const data = [];
for (let i=0; i<=2*Math.PI; i+=0.03) {
data.push(i, 50*Math.sin(i));
}
g.drawPath(PathSVG.polyline(data), {strokeColor:'red'});
}
Drawing Objects
Once a canvas drawing gets more complex with shapes needing modification or if we are going to animate them, the 'drawPath', 'drawImg' etc. methods are not well suited. The Path, Shape, Img, Text and ClipMask classes have methods to apply dynamic transforms, enable drag-and-drop change style properties etc. These objects can be modified and 'rendered' to create composite displays or erased and redrawn to create animations.
Any object are created by calling its constructor.
const pathobj = new Path(pathDef, options); const shapeobj = new Shape(outlineDef, options); const imgobj = new Img(imgDef, options); const txtobj = new Text(strg, options); const mask = new ClipMask(outlineDef, options);
Each class constructor take as arguments a descriptor and an options object specifying construction transforms and style specifiers that will determine the appearance of the object when rendered to the canvas. The transforms properties applied by the constructor make make permanent modifications to the appearance of the object. Once instantiated these objects may be rendered by different Cango instances on any layer.
Path, Shape, ClipMask
Path, Shape and ClipMask objects can have their outline path defined by any of the following:
- a String of SVG "path" format commands ("M", "l", "C", "a", "A" etc) with their associated coordinates
- an Array of SVG "path" format commands ("M", "l", "C", "a", "A" etc) with their associated coordinates
- a PathSVG object which itself takes either a string or array of SVG path data and breaks it into an array of segments which can be manipulated using the PathSVG methods; translate, scale, rotate. It has methods to join two paths, reverse path direction and so on. PathSVG also has static methods which generate predefined paths and shape outlines; circle, arc, arcTo, ellipse, square, rectangle, triangle, cross and ex. It also has splineFit and polyLine methods to draw paths through a set of data points. PathSVG objects can be used as the tracks for Cango animations to move objects along this path.
Img
Img objects can take as a descriptor any of the following:
- a String specifying an image file URL
- an HTML Image object
- another Canvas element
If a URL is passed then the image is loaded into an HTML Image object. The image is asynchronously loaded (if not pre-loaded) and then rendered to the canvas.
Text
Text objects are specified by a String. The options properties then define the font-family, font size and weight etc.
Groups
Cango provides the Group object to enable multiple objects to be treated as a single entity when applying transforms and rendering to the canvas. Since other Groups can be added to a Group, family trees of objects can be created and so provide a mechanism for inheritance of transforms by descendant objects.
Dynamic transform methods
All individual Drawing Objects and Groups have dynamic transform methods useful for drag-n-drop and animation, These methods generate a transform matrix which is applied to the object coordinates when rendered. These transforms do not affect the object definition, the transforms are cleared after the object is rendered. The transforms applied to a Group are inherited by its children. Transforms applied to a specific object are applied in addition to anf after, any transforms inherited from a parent Group. The dynamic transforms are: 'skew', 'scale', 'rotate' and 'translate', and they are applied in order of insertion.
Pointer event methods
Handling of drag-n-drop or mouse click events on any object or Group can be enabled by the obj.enableDrag or obj.enableClickmethods. The 'enableClick' method takes a single parameter, the callback function to be called on a click event. The 'enableDrag' method takes from two to four parameters, the Group or object that forms the scene to be redrawn of each event and the callback functions to be called when any pointer mousemove, mousedown or mouseup event occurs. When called the callback functions are passed an EventData object which holds properties: target, pointerPos, dragPos, dragOfs, dragAngle and dragOfsAngle. Enabling drag-n-drop or click on a Group recursively enables drag-n-drop or click on all the group's descendent objects.
Cango provides the transformRestore which can restore the dynamic transforms to an object so that objects can be restore to their last 'as drawn' state, useful if some other object is moved and the scene re-drawn.
Fig 4. shows a simple example, a rectangle 'Shape' object. Just click and drag it to see the effect. The source code is shown to the left.
Figure 4. Example of drag-n-drop, click and drag the rectangle.
function dragBox(cvsID)
{
const boxOutline = ['M',0,0, 'l',40,0,0,100, -40,0, 'z'];
const box = new Shape(boxOutline, {
fillColor:'orange',
border:true,
strokeColor:"brown"});
function dragObj(evt)
{
evt.target.translate(evt.dragPos.x, evt.dragPos.y);
evt.gc.render(evt.target, true);
}
const g = new Cango(cvsID);
g.setWorldCoordsRHC(-100, -100, 400);
box.enableDrag(dragObj);
g.render(box);
}
Rendering Objects and Groups to the canvas
Once an object is created it can be drawn onto the canvas by the 'render' method of any Cango instance.
cgo.render(obj [, clear]);
The render method takes an drawing object (Path, Shape, Img or Text) or Group as its first parameter, if the optional 'clear' parameter is either Boolean true or the string "clear", the canvas is cleared prior to rendering the object or group. If this second argument is undefined any other value the canvas is not cleared and the object is rendered onto the canvas in addition to any existing drawing. For animations the canvas should be cleared before rendering each frame, so the second argument should be true for rendering each frame.
The order of drawing the children objects of a Group is in order of insertion. But note if a child element is a Group the children of the child Group will be rendered before the next child of the original Group and so on down the family tree.
Cango Extension modules
Various modules are available to assist more specialised drawing. The modules can provide Cango Extension Objects and additional methods for the Cango object.
Cango Extension Objects are sub-classes of the Cango Group object, the 'children' elements are instances of the basic Cango drawing objects Path, Shape, Img, Text, ClipMask or Group objects. Cango Extension Objects can have their own style properties, methods and event handlers. They still behave as core objects in that they can be transformed with scale, translate, rotate and skew methods.
Extension Objects are drawn using the Cango context's render method like any other Group. But they support a user defined 'preRender' method which is called by the Cango context prior to the render method. A 'preRender' method is passed a reference to the Cango context as its only argument. The 'preRender' method may then use information about the calling context, world coordinate system etc., to configure various properties of its children.
The extension current available are:
CangoAnimation
Cango methods added:
animation
playAnimation
stepAnimation
pauseAnimation
stopAnimation
CangoAnimation extension objects:
CangoAxes
CangoArrows
CangoTextUtils
CangoTextUtils extension objects:
CangoZoomPan
Cango method added: