MISCELLANEOUS TECHNICAL ARTICLES BY Dr A R COLLINS

Cango User Guide

Cango

This page is a reference manual for the methods and properties of the Cango canvas graphics library. For an introduction to Cango see Cango Graphics page. The latest release if Version 18 and the source code may be downloaded at Cango-18v10.js and a minified version at Cango-18v10-min.js.

Cango constructor

Syntax:

var cgo = new Cango(canvasID);

var cgo = new Cango(canvasElement);

Description:

To start drawing, an instance of the Cango graphics context must be created. This requires a reference to an existing canvas element either in the web page or off-screen in memory. Pass the canvas ID or a reference to the canvas object to the Cango constructor and the Cango graphics object is returned.

Parameters:

canvasID or canvasElement: String or HTMLCanvasElement - The 'id' property of the canvas object or a reference to the canvas element on which the Cango library will draw.

Returns:

Cango object.

Cango Methods

Setting up world coordinates

A Cango graphics context refers all its drawing dimensions to a world coordinate grid which can be either the RHC which is uses the standard Right Handed Cartesian coordinates or SVG which used the left handed Cartesian coordinates used by in SVG system and raw canvas graphics. The system used is set by a call to either setWorldCoordsRHC or setWorldCoordsSVG.

The RHC coordinates X axis values increase to the RIGHT, Y axis values increase UP the canvas, and angles increase anticlockwise (CCW).

To set up a RHC system call:

cgo.setWorldCoordsRHC(gbLowerLeftX, gbLowerLeftY, gbWidth, gbHeight);

The SVG coordinates X axis values increase to the RIGHT, Y axis values increase DOWN the canvas, and angles increasing clockwise (CW).

To set up a SVG system call:

cgo.setWorldCoordsSVG(gbLowerLeftX, gbLowerLeftY, gbWidth, gbHeight);

The SVG coordinates X axis values increase to the RIGHT, Y axis values increase DOWN the canvas, and angles increasing clockwise (CW) see Fig. 1b.

World coordinate scaling

To set the X and Y scaling of world coordinates Cango uses a gridbox. Every Cango instance has its own gridbox. This is set to the full canvas by default, but the size and position of the gridbox may be controlled by defining some padding distances from the canvas sides.

The setWorldCoordsRHC method defines the X, Y coordinates of the LOWER LEFT corner of the gridbox and the width and height of the gridbox in world coordinate units. X and Y dimensions can be in different units.

The setWorldCoordsSVG defines the X, Y coordinates of the UPPER LEFT corner of the gridbox, and the width and height of the gridbox in world coordinate units.

If isotropic scaling (square pixels) is required, omit the 'gbHeight' argument and the Y scale factor will be set equal to the X scale factor:

  cgo.setWorldCoordsSVG(gbLowerLeftX, gbLowerLeftY, gbWidth); // square pixels

The gridbox padding width is expressed as a percentage of the canvas width. Fig. 2 shows examples of gridboxPadding and the way setWorldCoordsRHC and setWorldCoordsSVG use the gridbox to define their coordinates. Axes have been drawn to demonstrate the different scaling. The methods called were:

const cgo = new Cango(cvsID);
cgo.gridboxPadding(10, 10, 5, 5);
cgo.setWorldCoordsRHC(0, 0, 300, 5);
cgo.fillGridbox("lightgreen");
cgo.drawAxes();
  
Figure 1. Setting the world coordinates using the setWorldCoordsRHC with independent X and Y scaling.
const cgo = new Cango(cvsID);
cgo.gridboxPadding(10, 5, 5, 10);
cgo.setWorldCoordsSVG(0, 0, 300);
cgo.fillGridbox("lightpink");
cgo.drawAxes();
  
Figure 2. Setting the world coordinates using the setWorldCoordsSVG with square pixels.

Coordinate system methods

gridboxPadding

Syntax:

cgo.gridboxPadding([left[, bottom[, right[, top]]]]);

Description:

The gridbox provides the reference point for the world coordinate origin and the gridbox width and height provide a reference distance for setting the world coordinate scaling in the X and Y directions. the gridboxPadding method is used to control the gridbox position and dimensions by setting the padding from each edge of the canvas.

If only 'left' is specified then this values sets the padding on all sides of the gridbox. If 'left' and 'bottom' are defined then the right and top padding are set to the same values. If the 'top' is undefined then top is set equal to the bottom.

Note: The Cango property 'cgo.heightPW' holds the height of the canvas measured in units of percent of the canvas width, this is often useful in setting the gridbox padding.

If no call is made to gridboxPadding then the default gridbox is the full canvas. Any call to change gridboxPadding resets the world coordinates to their default which is equivalent to calling setWorldCoordsSVG() i.e. the coordinate origin will be the upper left corner of the gridbox and the scaling is 1 to 1 with the canvas pixels.

Parameters:

left: Number - (optional) Width of the padding from left edge of the canvas to the left of the gridbox.

bottom: Number - (optional) Width of the padding from bottom edge of the canvas to the bottom of the gridbox.

right: Number - (optional) Width of the padding from right edge of the canvas to the right of the gridbox.

top: Number - (optional) Width of the padding from top edge of the canvas to the top of the gridbox.

All padding values should be positive numbers in units of percent of canvas width.

fillGridbox

Syntax:

cgo.fillGridbox(fillColor);

Description:

Fills the current gridbox area with the color fillColor.

Parameters:

fillColor:String or color gradient- The fill color may be solid color defined by a string in one of the CSS color formats or if a gradient color is to be used, a reference to a LinearGradient or RadialGradient object should be passed, see Colors. If 'fillGridbox' is called with no 'fillColor' parameter then the gridbox is filled with the current Cango default fillColor. If not set by the application, the default fillColor is "rgba(128,128,128,1.0)" which is gray.

setWorldCoordsRHC

Syntax:

cgo.setWorldCoordsRHC([gbLowerLeftX, gbLowerLeftY, gbWidth [, gbHeight]]);

Description:

Defines a Right Handed Cartesian coordinate grid for subsequent drawing operations with the cgo graphics context. RHC coordinates have the X axis values increase to the RIGHT, Y axis values increase UP the canvas and angles increase ANTI-CLOCKWISE. The world coordinate system sets translation and scaling factors to map world coordinate values to canvas drawing pixels. This is done by specifying the world coordinate values of the Cango context's gridbox origin and the width and height of the gridbox in world coordinate units. The 'gbLowerLeftX, gbLowerLeftY' will be the world coordinate values of the lower left corner of the gridbox. Specifying the gridbox width in world coordinate units determines the X axis scale factor (cgo.xscl) and specifying the gridbox height in world coordinates Y axis units will determine the Y axis scale factor (cgo.yscl). If no value is passed for the 'gbHeight' then the magnitude of the Y axis scale factor will be set equal to the X axis scale factor resulting in square pixels.

Calling 'setWorldCoordsRHC' with no parameters results in the lower left corner of the gridbox being set to 0,0 in world coordinates and X and Y axes scaled in canvas pixels.

Note: The world coordinate system extends to the full size of the canvas.

Note: If no call has been made to either 'setWorldCoordsRHC' or 'setWorldCoordsSVG', then the world coordinate system will be SVG style equivalent to calling cgo.setWorldCoordsSVG().

Parameters:

gridOrgX: Number - World coordinate X value of the gridbox lower left corner.

gridOrgY: Number - World coordinate Y value of the gridbox lower left corner.

gridboxWidth: Number - The width of the gridbox measured in world coordinate X axis units.

gridboxHeight: Number - The height of the gridbox measured in world coordinate Y axis units. If 'gbHeight' is omitted then Y axis units are assumed equal to X axis units and so Y scaling is set to equal the X scaling, resulting in square pixels.

Example:

Here is a typical world coordinate setup where gridboxPadding 10% around the gridbox. Then setWorldCoordsRHC fixes the origin (lower left corner) to be 0,0 and the plotting area to be 250 units wide and 3 units high.

function setCoordsDemo(cvsID)
{
  const g = new Cango(cvsID);

  g.clearCanvas("lightyellow");
  g.gridboxPadding(10);
  g.fillGridbox("lightgreen");
  g.setWorldCoordsRHC(0,0, 250,3); 
  g.drawAxes();
}
setWorldCoordsSVG

Syntax:

cgo.setWorldCoordsSVG([gbUpperLeftX, gbUpperLeftY, gbWidth [, gbHeight]]);

Description:

Defines an SVG (Left Handed Cartesian) coordinate grid for subsequent drawing operations with the cgo graphics context. SVG coordinates have the X axis increase to the RIGHT and Y axis increase DOWN the canvas and angles increase CLOCKWISE. This is the sign convention used when drawing with canvas CanvasRenderingContext2D commands. The world coordinate system sets translation and scaling factors to map world coordinate values to canvas drawing pixels. This is done by specifying the world coordinate values of the Cango context's gridbox upper left corner and the width and height of the gridbox in world coordinate units. Specifying the gridbox width in world coordinate units determines the X axis scale factor (cgo.xscl) and specifying the gridbox height in world coordinates Y axis units will determine the Y axis scale factor (cgo.yscl). If no value is passed for the 'gbHeight' then the magnitude of the Y axis scale factor will be set equal to the X axis scale factor resulting in square pixels.

Calling 'setWorldCoordsSVG' with no parameters results in the upper left of the gridbox being set to 0,0 and X and Y axes scaled in canvas pixels.

Note: The world coordinate system extends to the full size of the canvas.

Note: If no call has been made to either 'setWorldCoordsRHC' or 'setWorldCoordsSVG', then the world coordinate system will be SVG style equivalent to calling cgo.setWorldCoordsSVG().

Parameters:

gridOrgX: Number - World coordinate X value of the gridbox upper left corner.

gridOrgY: Number - World coordinate Y value of the gridbox upper left corner.

gridboxWidth: Number - The width of the gridbox measured in world X axis units.

gridboxHeight: Number - The height of the gridbox measured in world Y axis units. If 'gridboxHeight' is omitted then Y axis units are assumed equal to X axis units and so Y scaling is set to equal the X scaling, resulting in square pixels.

dupCtx

Syntax:

cgo.dupCtx(sourceCtx);

Description:

This method copies the graphics context properties from one Cango context 'sourceCtx' into the 'cgo' context. When drawing onto layers, this method provides a simple way to copy the underlying Cango coordinate system so the new layer's world coordinates match. The 'dupCtx' method copies all the properties excluding the 'cvs' and 'cId'. Properties are copied by value so that after the call changing either 'sourceCtx' or 'cgo' properties will have no effect on the other.

Parameters:

sourceCtx: Cango graphics context - The source Cango instance from which the properties are copied and used to set the calling context properties.

toPixelCoords

Syntax:

var posObj = cgo.toPixelCoords(xWC, yWC);

Description:

This method converts the x and y coordinates of a point expressed in world coordinates to an object with x and y properties that hold the raw canvas pixel coordinates of the point.

Note: Canvas pixel coordinates set are set by the 'width' and 'height' attributes of the canvas element. These may differ from screen pixel coordinates if the canvas element style sets different width and height values. Cango prevents any confusion by setting the canvas attributes to match screen pixels when the Cango graphics context is created. So toPixelCoords always returns the canvas pixel coordinates which map 1 to 1 with screen pixels.

Parameters:

xWC, yWC:Numbers - X and Y coordinates of a point measured in world coordinates.

Returns:

Object - {x: , y: } An object with the following properties:

x, y: Numbers - The X and Y coordinates of the point measured in canvas pixel coordinates, equal to screen pixels.

toWorldCoords

Syntax:

var posObj = cgo.toWorldCoords(xPX, yPX);

Description:

This method converts the coordinates (xPX, yPX) of a point expressed in canvas pixels coordinates to an object with x and y properties that hold the world coordinates of the point. There can be more than one Cango graphics context on a canvas, the world coordinates of the point in the calling graphics context are returned.

Parameters:

xPX, yPX: Numbers - X and Y coordinates of a point measured in pixel coordinates.

Returns:

Object - {x: , y: } An object with two properties x, y which hold the world coordinates the point.

Layer methods

The functionality of a CanvasStack is built into Cango. Transparent canvas overlays can be created to assist in drawing data cursors, and animation.

Layers can be drawn upon and cleared independent of the background canvas or other layers, so animations or drag-n-drop handlers can erase their canvas and re-draw at each frame or move event without affecting the content on other layers.

Any number of layers can be created by a Cango instance hosted on a background canvas. Off-screen canvases don't support layers and only Cango instances hosted on the background canvas can create layers.

Note: Detection of a 'grab' event on an object for drag-and-drop, works regardless of the layer on which the object is drawn. When a drag-n-drop mouse event occur on a canvas stack, each object enabled for drag-and-drop on each layer is checked to see if the event coordinates are within its outline. The first Obj2D encountered that has drag-n-drop enabled on itself or its parent Group determines the event handler to be called. The layers are searched starting at the top (last canvas added) and going down to the background canvas.

createLayer

Syntax:

var ovlID = cgo.createLayer();

Description:

Creates a transparent canvas overlaying the background canvas. The overlay canvas will be the same size as the background canvas and will be transparent. A unique ID string is generated and assigned to the new canvas, this ID string is the return value from the method.

Only Cango contexts that are created on the original background canvas can create layers, calling 'createLayer' as a method of a Cango instance on an overlay layer does nothing and returns an empty string.

To draw on the new layer, an instance of Cango should be created on the overlay by calling the Cango constructor passing the layer's ID string. The properties of the background canvas can be readily copied to the new Cango context using the cgo.dupCtx method.

Parameters:

none

Returns:

String - The unique ID string of the newly created canvas element.

deleteLayer

Syntax:

cgo.deleteLayer(ovlID);

Description:

Deletes an existing canvas overlay specified by its ID string. The ID of a canvas layer is returned from the 'createLayer' method. The 'deleteLayer' method will remove the layer's canvas from the DOM. The canvas can be anywhere within the stack except the background canvas which cannot be deleted with this method.

Parameters:

ovlID: String - The ID attribute of the canvas element to be deleted.

deleteAllLayers

Syntax:

cgo.deleteAllLayers();

Description:

Deletes all existing canvas layers leaving only the original background canvas. The overlay canvas elements are deleted from the DOM.

Parameters:

none

Basic drawing methods

Cango provides four basic methods for simple, single use, drawing of objects onto the canvas. They are:
drawPath,  drawShape,  drawImg,  drawText.

These methods take as parameters a 'descriptor' and an 'options' object which sets various properties that determine the appearance and position of the object on the canvas. They create the corresponding object type, apply all the style options and render the object to the canvas.

drawPath

Syntax:

cgo.drawPath(pathData [, options]);

Description:

Creates a Path object defined by the 'pathData' Path2D object and sets any of its properties as specified in the 'options' object then renders the Path onto the canvas.

Parameters:

pathData: Path2D, String or Array - A Path2D, an SVGsegs array or a string or array consisting of a series of command letters and their associated parameters in SVG path data format. The full SVG command set is supported (see SVG syntax for the command descriptions).

options: Object - The key-values of this object are used to set the corresponding properties of the Path object.

Path options properties are:

  • x
  • y
  • scl
  • rot
  • skewX
  • skewY
  • strokeColor
  • lineWidthWC
  • lineWidth
  • lineCap
  • iso
  • dashed
  • dashOffset
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor

The outline path coordinates are specified as world coordinate values reference to origin 0,0. The 'x' and 'y' optional properties can specify where this path origin will be drawn in world coordinates. For details of the other option properties see Object Properties.

drawShape

Syntax:

cgo.drawShape(pathData [, options]);

Description:

Creates a Shape object defined by the 'pathData' parameter and sets any of its properties as specified in the 'options' object then renders the Path onto the canvas. The outline path is closed and the Shape formed is filled with color.

Parameters:

pathData: Path2D, String or Array - A Path2D, an SVGsegs array, or a string or an array consisting of a series of command letters and their associated parameters in SVG path data format. The full SVG command set is supported (see SVG syntax for the command descriptions).

options: Object - The key-values of this object are used to set the corresponding properties of the Shape object.

Shape options properties are:

  • x
  • y
  • scl
  • rot
  • skewX
  • skewY
  • fillColor
  • fillRule
  • strokeColor
  • lineWidthWC
  • lineWidth
  • iso
  • dashed
  • dashOffset
  • border
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor

The outline path coordinates are specified as world coordinate values reference to origin 0,0. The 'x' and 'y' optional properties can specify where this path origin will be drawn in world coordinates. For details of the other properties see Object Properties.

drawImg

Syntax:

cgo.drawImg(imgSpec [, options]);

Description:

Renders an Image specified by 'imgSpec' onto the canvas. The imgSpec can be a URL String, a pre-loaded Image object or a Canvas element. The properties of the 'options' object (if present) can specify where the image is positioned and how it is formatted. When fully loaded the Img is rendered onto the canvas.

Parameters:

imgSpec: Image, Canvas or URL String - The pre-loaded Image object, a HTML Canvas element or the URL of the image to be loaded and then rendered to the canvas.

options: Object - The key-value pairs of this object set the corresponding Img properties.

Img options properties are:

  • x
  • y
  • scl
  • rot
  • skewX
  • skewY
  • strokeColor
  • lineWidthWC
  • lineWidth
  • dashed
  • dashOffset
  • border
  • imgWidth
  • imgHeight
  • lorg
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor

The image is positioned on the canvas so that its drawing origin is at 0,0 in the world coordinate system. Where the drawing origin is on the Image is specified by the "Locate Origin" property lorg. The 'x' and 'y' optional properties can also be used to specify where this drawing origin is relative to the Image. For details of the other properties see Object Properties.

drawText

Syntax:

cgo.drawText(str [, options]);

Description:

Renders a Text object onto the canvas. The text is specified by the string 'str'. The 'options' object (if present) can specify where the Text is positioned and how it is formatted. The text is then rendered onto the canvas.

Parameters:

str: String - The text string to be written.

options: Object - The key-value pairs of this object set the corresponding Text object Properties.

Text options properties are:

  • x
  • y
  • scl
  • rot
  • skewX
  • skewY
  • strokeColor
  • fillColor
  • lineWidthWC
  • lineWidth
  • dashed
  • dashOffset
  • border
  • fontFamily
  • fontSize
  • fontWeight
  • lorg
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor

The Text string is drawn on the canvas so that its drawing origin is at 0,0 in the world coordinate system. Where the drawing origin is within the bounding box of the Text is specified by the "locate origin" property lorg property. The 'x' and 'y' optional properties can also specify where the drawing origin will be relative to the Text. For details of the other properties see Object Properties.

clearShape

Syntax:

cgo.clearShape(pathData [, options]);

Description:

Creates a Shape defined by the 'pathData' parameter and sets any of its formatting properties specified by the 'options' parameter and clears this area of the canvas back to its background color. 'pathData' can be a Path2D, an SVGsegs array or a string or an array holding a series of commands and their associated coordinates in the SVG path data syntax. The outline path is closed and the shape formed is cleared. The 'options' object (if present) can specify where the Shape is positioned and how it is scaled or rotated when rendered.

Parameters:

pathData: Path2D, String or Array - A string or an array holding commands and coordinates in SVG path data format, the full SVG command set is supported (see SVG syntax for the command descriptions).

options: Object - The various Shape object properties can be set by assigning the desired value to the corresponding options property.

Shape options properties are:

  • x
  • y
  • scl
  • rot
  • skewX
  • skewY
  • iso
clearCanvas

Syntax:

cgo.clearCanvas([fillColor]);

Description:

Clears the canvas, deleting all drawing, images and text. The canvas may be optionally filled with the color fillColor. If 'clearCanvas' is called 'fillColor' undefined, or null the canvas is cleared back to its background color which is set by the HTML canvas element style. All graphics drawing contexts are left intact. Listening for mousedown events on any draggable objects is canceled.

Parameters:

fillColor: String or color gradient - An optional fill color defined by a string in one of the CSS color formats or if a gradient color is to be used a reference to a LinearGradient or RadialGradient object should be passed, see Colors section for detailed syntax.

setPropertyDefault

Syntax:

cgo.setPropertyDefault(propertyName, val);

Description:

Sets the default values for various properties. The property default to be set is specified by the string 'propertyName' this string is not case sensitive and may take the values set out in column 1 of the table below.

The new default value is passed as 'value'. The value is restricted to be within the range of values appropriate to the property. If the property is not one of the string values listed or the value is an incorrect type or is outside the allowed range of values then the call is ignored and the current default value remains unaltered.

If no call is made to 'setPropertyDefault' for a particular property, then the property value remains at its system default value listed in column 4.

NameTypeRangeDefault
fillColorCSS Color-"rgba(0, 0, 0, 1.0)"
strokeColorCSS Color-"rgba(128, 128, 128, 1.0)"
lineWidthNumber (pixels)-1
lineCapString"butt", "round", "square""butt"
fontFamilyStringCSS font family definitions"Consolas, Monaco, 'Andale Mono', monospace"
fontSizeNumber (pixels)>012
fontWeightString or Number"bold", "normal", 100, 200, ..900400
stepTimeNumber (msec)16 .. 50050
frameRate"auto" or Number"auto" or 0.5 .. 50 frames/sec"auto"

NB: fontSize pixel value is converted to the equivalent world coordinate value so that fontSize can be scaled with transform methods.

Parameters:

propertyName: String- The name of the property whose default value is to be set. It must be one of the strings listed in column 1 of the table above. The string value is not case sensitive.

value- The new default value for the property. Its type should match the type listed in column 2 of the table above and the range of values must fall within the range listed in column 3.

Animation methods

CangoAnimation extension module is available to provide additional Cango methods to enable creation and control of canvas animations. These are detailed in the Cango Animation user guide.

Axes drawing methods

CangoAxes extension module is available to provide additional Cango methods to assiat in drawing and labeling axes for use when plotting data using the Cango library. These are detailed in the Cango Axes user guide.

Cango public properties

The following table describes the various properties available for each Cango graphics context. They may be helpful in setting up lower leveling graphics applications.

PropertyTypeDescription
ctxCanvasRenderingContext2DThe raw canvas drawing context. This is available to access the more esoteric canvas capabilities.
xsclNumberThe X axis scaling factor. World coordinate X axis values are multiplied by cgo.xscl to convert to pixels.
ysclNumberThe Y axis scaling factor. World coordinate Y axis values are multiplied by cgo.yscl to convert to pixels. cgo.yscl will always be a negative value for RHC coordinate systems and positive for SVG coordinate systems.
heightPWNumberThe canvas height expressed as a percentage of the canvas width. cgo.heightPW is often useful in setting gridboxPadding.
widthPWNumberThe canvas width expressed as a percentage of the canvas width, so always equal to 100. (Provided for completeness with the more useful heightPW).
aRatioNumberAspect ratio of the canvas element, the canvas width divided by canvas height. If the canvas is 300px wide and 200px high, cgo.aRatio = 1.5.
rawWidthNumberThe canvas width in pixels.
rawHeightNumberThe canvas height in pixels.
Properties added by CangoAnimation module
stepTimeNumberThe time interval along the animation timeline taken for each call of 'stepAnimation'. Default value 50 msec.
frameRate"auto" or NumberThe animation frame rate. The number of frames per second drawn as an animation traverses the timeline. Default is "auto" which uses the 'requestAnimationFrame' utility to set the frame rate at approximately 60 frames/sec.

Path, Shape, Img, Text, ClipMask objects

When an object is to be rendered to the canvas more than once as for animation or drag-and-drop, it is more efficient to reuse the object applying dynamic transforms and modifying properties prior to each rendering. Cango provides five object classes for this purpose: Path, Shape, Img,Text and ClipMask. These are all sub-classes of the generic Obj2D and inherit Obj2D's methods. Once instantiated these Obj2D may be rendered by different Cango instances on any layer.

All the five object constructors take two parameters, a 'descriptor' parameter defining the particular object. This may be a set of SVG path commands defining the outline for Path, Shape and ClipMask, or a URL or HTML Image for Img objects or a string for Text objects. The second optional parameter is an object whose key-value pairs set initial values for Obj2D properties.

  var obj = new Path(descriptor [, options]);
  var obj = new Shape(descriptor[, options]);
  var obj = new Img(descriptor[, options]);
  var obj = new Text(descriptor[, options]);
  var obj = new ClipMask(descriptor[, options]);
  

Path, Shape, ClipMask descriptors

Path, Shape and ClipMask constructors have their path or shape outline described by a series of SVG "path" format commands ("M", "l", "C", "a", "A" etc) with their associated parameters and coordinates. These SVG data can be represented in any of four formats;

  • Array
    const desc = ["M",8.24,-0.1, "l",1.2,0.2, 0,1.6, -1.2,0.2, "A",8.3,8.3, 0,0,1, 4.9,6.6"];
  • String
    const desc = "M8.24,-0.1 l1.2,0.2 0,1.6 -1.2,0.2 A8.3,8.3 0 0 1 4.9,6.6";
  • SVGsegs
    const desc = new SVGsegs("M8.24,-0.1 l1.2,0.2 0,1.6 -1.2,0.2 A8.3,8.3 0 0 1 4.9,6.6");
    const desc = new SVGsegs(["M",8.24,-0.1, "l",1.2,0.2, 0,1.6, -1.2,0.2, "A",8.3,8.3, 0,0,1, 4.9,6.6"]);
    const desc = segment("M 8.24,-0.1 l 1.2,0.2 0,1.6 -1.2,0.2 A 8.3,8.3 0 0 1 4.9,6.6");
  • Path2D
    const desc = new Path2D("M8.24,-0.1 l1.2,0.2 0,1.6 -1.2,0.2 A8.3,8.3 0 0 1 4.9,6.6");

SVGsegs path descriptors

To facilitate modifying SVG path data, Cango 17+ added the SVGsegs object, an array whose elements define the segments of the path. The SVGsegs constructor takes an array or string of SVG data and parses it into segments each using only 'M', 'L', 'C' and 'Z' commands and its absolute coordinates. The SVGsegs array returned has methods to transform and modify the path. These include translate, rotate, scale and skew methods along with methods dup, joinPath, appendPath and revWinding. These methods all return a new SVGsegs object so that the methods can be chained in typical functional programming style.

SVGsegs constructor

Syntax:

var pathSegData = new SVGsegs(data);

Description:

This constructor converts an array or string of SVG commands and associated parameters into an array, each element of which is an object defining a single segment of the path. The data format for each segment is the SVG 2 SVGPathSegment format ie. {type: char , values: [...]}. This data format is returned by the SVG2 'getPathData' method with its 'normalize' property set 'true'. The normalize option restricts the commands used to "M", "L", "C" and "Z" and the coordinates to be all absolute (reference to 0,0) not relative to the previous point's coordinates.

Parameters:

data: String or Array - holding a series of commands and their associated parameters. The full SVG set of commands is supported (see SVG syntax).

Returns:

Array - the array elements are objects with property 'type': a single letter string specifying an SVG command and 'values': an array of coordinates.

Example

var path1 = new SVGsegs("M 8.24,-0.1 l 1.2,0.2 0,1.6 -1.2,0.2 A 8.3,8.3 0 0 1 4.9,6.6");
console.log(path1);  // [{type:'M', values:[8.24,-0.1]}, 
                         {type:'L', values:[10.44,0.1]}, 
                         ... ]
    

SVGsegs Methods

appendPath

Syntax:

obj1.appendPath(data);

Description:

The appendPath method extends obj1 segments array by appending the obj2 segments. Since the obj2 commands must start with a 'M' command the resulting path has a separate, non contiguous section added.

Parameters:

data: SVGsegs object - The SVG path data defining a path to be appended to obj1.

Returns:

SVGsegs object - Array defining original obj1 path with sub-path 'data' appended.

dup

Syntax:

var newObj = obj.dup();

Description:

The dup method creates a new SVGsegs object, copying the segments array and all the methods from the original into the new object. This method is useful in creating complex objects made from similarly shaped components.

Parameters:

none.

Returns:

SVGsegs object - Array defining a path identical to obj1 path.

joinPath

Syntax:

obj1.joinPath(data);

Description:

The joinPath method extends obj1.segments array by adding the obj2.segments array. The initial 'M' command segment is deleted so that the resulting path is continuous and extended.

Parameters:

data: Array or String of SVG data - The SVG command data defining a path to be joined to obj1.

Returns:

SVGsegs object - Array defining a path comprising the original obj1 path extended by joining on the path defined by 'data'.

revWinding

Syntax:

var newObj = obj.revWinding();

Description:

The revWinding method creates a Array containing SVG data commands which would appear the same as the original when rendered to a canvas but the path segments and coordinates are rearranged to be traversed in reverse order. This method is useful when creating complex objects made from similarly shaped components with point or line symmetry and for creating holes in Shapes when filled by 'nonzero' fill rule.

Parameters:

none.

Returns:

SVGsegs object - Array defining a path appearing identical to the original 'obj' but the path is traversed in the opposite direction as the segments are rendered to the canvas.

rotate

Syntax:

var newObj = obj.rotate(degs);

Description:

The rotate method rotates all the obj.segments coordinates by 'degs' degrees centered on the drawing origin (0,0). The method returns a new Array containing the rotated coordinates. The original 'obj' remains unaltered.

Parameters:

degs: Number - The angle of rotation measured in degrees counter-clockwise for RHC coordinate grids and clockwise for SVG coordinate grids.

Returns:

SVGsegs object - Array defining a path identical to obj1 path but rotated about world coordinate origin by the angle 'degs' degrees.

scale

Syntax:

var newObj = obj.scale(xScale[, yScale]);

Description:

The scale method multiplies all obj.segments X coordinates by 'xScale' and Y coordinates by 'yScale' (if specified). If 'yScale' is undefined then 'xScale' value is used to scale the Y dimensions. This scaling effectively changes the size of the path as it will be rendered to the canvas. The scaling is centered on the drawing origin (0,0). The method returns a new Array object containing the scaled coordinates. The original 'obj' remains unaltered.

Parameters:

xScale: Number - A number by which the object's X dimensions are scaled, negative numbers will flip the object horizontally.

yScale: Number - (optional) A number by which the object's Y dimensions are scaled, negative numbers will flip the object vertically.

Returns:

SVGsegs object - Array defining a path identical to obj1 path but with all coordinates scaled.

skew

Syntax:

var newObj = obj.skew(degH, degV);

Description:

The skew method skews all obj X coordinates by an angle of 'degH' from the vertical axis leaving, and skews the Y coordinates by an angle of 'degV' from the horizontal axis. The method returns a new Array containing the original commands with the skewed coordinates. The original 'obj' is remains unaltered.

Parameters:

degH: Number - Angle by which all coordinates are skewed from the X axis. Measured in degrees counter-clockwise for RHC coordinate systems and clockwise for SVG coordinate systems.

degV: Number - Angle by which all coordinates are skewed from thge Y axis. Measured in degrees counter-clockwise for RHC coordinate systems and clockwise for SVG coordinate systems.

Returns:

SVGsegs object - Array defining a path identical to obj1 path but with the coordinates skewed.

translate

Syntax:

var newObj = obj.translate(x, y);

Description:

The translate method adds the values x and y to all segments array coordinates of 'obj'. Effectively making a permanent shift of the object by x and y from the drawing origin (0, 0). The method returns a new Array containing the translated coordinates. The original 'obj' remains unaltered.

Parameters:

x, y: Numbers - distance by which the object's drawing origin is offset from the world coordinate origin.

Returns:

SVGsegs object - Array defining a path identical to obj1 path but shifted by distance 'x' along the X axis and 'y' along the Y axis.

segment wrapper function

Cango supplies new global function segment, a wrapper function to create SVGsegs objects from a string or array of SVG data path data: segment = (d)=>new SVGsegs(d);

Example:

  const right = segment(["M",0, 10, "C", 5,12, 3,3, 0,0]);

The 'right' constant is an SVGsegs object defining the outline of the right half of a heart shape. The left outline can be formed by flipping horizontally (scaling X coords by -1) and then reversing its winding direct. Finally the two halves can be joined forming a continuous heart shaped outline, 'pth', drawn in green, as shown below

A segment example.

function testSegment(cvsID){
  const right = segment(["M",0, 10, "C", 5,12, 3,3, 0,0]);
  const left = right.scale(-1, 1).revWinding();
  const pth = right.joinPath(left);

  const g = new Cango(cvsID);
  g.setWorldCoordsRHC(-8, -2, 16);
  g.drawShape(pth, {fillColor:"green"});
}

Outline path generators

To simplify the creation of Path, Shape and ClipMask descriptors for commonly used shapes, the following functions are provided. These all return an array of SVG command and coordinate data that can be passed to the Obj2D constructors.

circle

Syntax:

var shapeData = circle(d);

Description:

This function returns an array containing SVG commands defining the outline path of a circle with diameter 'd'. The returned array is suitable as input parameter for the Path, Shape and ClipMask objects. The drawing origin will be at the center of the circle.

Parameters:

d:Number - Diameter of the circle measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the circle.

ellipse

Syntax:

var shapeData = ellipse(w, h);

Description:

This function returns an array containing SVG commands defining the outline of a ellipse with width (X axis) 'w' and height (Y axis) 'h'. The returned array is suitable as input parameter for the Path, Shape and ClipMask objects. The drawing origin will be at the center of the ellipse.

Parameters:

w:Number - The X axis width of the ellipse measured in the world coordinates.

h:Number - The Y axis height of the ellipse measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the ellipse.

arc

Syntax:

var shapeData = arc(radius, startAngle, endAngle, anticlockwise);

Description:

This function returns an array containing SVG commands defining the outline of a circular arc with radius 'radius'. The center of the arc will be the origin (0,0) and will start at angle 'startAngle' and end at 'endAngle'. The direction of sweep is set by the 'anticlockwise' argument.

Parameters:

radius: Number - The circular arc radius.

startAngle: Number - The angle from which the arc starts its sweep, measured in degrees.

endAngle: Number - The angle from which the arc ends its sweep, measured in degrees.

anticlockwise: Boolean - If true, the direction of arc sweep is anticlockwise, else it is clockwise.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the arc.

ellipticalArc

Syntax:

var shapeData = ellipticalArc(radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

Description:

This function returns an array containing SVG commands defining the outline of a elliptical arc with radius along X axis 'radiusX' and radius along the Y axis 'radiusY'. The center of the arc will be the origin (0,0) and will start at angle 'startAngle' and end at 'endAngle'. The direction of sweep is set by the 'anticlockwise' argument. The arc may be rotated so that the major axis is at an angle 'rotation' from the X axis.

Parameters:

radiusX: Number - The semi-major axis length (along X axis).

radiusY: Number - The semi-minor axis length (along Y axis).

rotation: Number - The angle of rotation of semi-major axis from the X axis measured in degrees.

startAngle: Number - The angle from which the arc starts its sweep, measured in degrees.

endAngle: Number - The angle from which the arc ends its sweep, measured in degrees.

anticlockwise: Boolean - If true, the direction of arc sweep is anticlockwise, else it is clockwise.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the arc.

square

Syntax:

var shapeData = square(s);

Description:

This function returns an array containing SVG commands defining the outline of a square with sides of length 's'. The returned array is suitable as input parameter for the Path, Shape and ClipMask objects. The drawing origin will be at the center of the square.

Parameters:

s:Number - Side length of the square measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the square.

rectangle

Syntax:

var shapeData = rectangle(w, h[, rad]);

Description:

This function returns an array containing SVG commands defining the outline of a rectangle with width 'w' and height 'h'. The rectangle may optionally have its corners rounded with a user defined radius. The returned array is suitable as input parameter for the Path, Shape and ClipMask objects. The drawing origin will be at the center of the rectangle.

Parameters:

w:Number - The width (X dimension) of the rectangle, measured in the world coordinates.

h:Number - The height (Y dimension) of the rectangle, measured in the world coordinates.

rad:Number - The radius of rounded corners applied to the rectangle, measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the rectangle.

triangle

Syntax:

var shapeData = triangle(s);

Description:

This function returns an array containing SVG commands defining the outline of an equilateral triangle with sides of length 's'. The returned array is suitable as input parameter for the Path, Shape and ClipMask objects. The drawing origin will be at the center of the triangle.

Parameters:

s:Number - The length of each side of the triangle measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the triangle.

cross

Syntax:

var pathData = cross(s);

Description:

This function returns an array containing SVG commands defining a cross with horizontal and vertical arms of length 's'. The returned array is suitable as input parameter for the Path objects. The drawing origin will be at the center of the cross.

Parameters:

s:Number - The length of the horizontal and vertical arms of the cross, measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the cross.

ex

Syntax:

var pathData = ex(s);

Description:

This function returns an array containing SVG commands defining an X with arm lengths 's'. The returned array is suitable as input parameter for the Path objects. The drawing origin will be at the center of the ex.

Parameters:

s:Number - The length of each arm of the ex, measured in the world coordinates.

Returns:

Array - Array of SVG format commands and associated coordinate pairs defining the outline of the ex.

Object common methods

All Path, Shape, Img, Text and ClipMask objects have the following common methods inherited from the Obj2D prototype.

setDescriptor

Syntax:

obj.setDescriptor(newDescriptor);

Description:

Provides a way to change an object's definition. Object definition is initially set by the descriptor passed to the constructor but the the descriptor may be changed after construction without impact on all the object properties by calling 'setDescriptor' passing the new object definition.

Parameters:

newDescriptor: Various - The descriptor should be of the type that is expected by the different types of Obj2D, Path, Shape and ClipMask require a Path2D, String, Array or SVGsegs object, an Img requires a URL or Image object etc.

setProperty

Syntax:

obj.setProperty(propertyName, val);

Description:

Provides an alternate way to set an object's properties which are usually set by key-value pairs in the 'options' argument of the Path constructor. After construction the 'setProperty' method may be called to set a property's value. Most properties set by this method over-ride any previously set value. The exceptions are the x, y, rot, scl, skewX and skewY values which are applied in order of insertion, are permanent and cumulative.

Parameters:

propertyName: String - The property to have its value set. The string is not case sensitive and may take the values set out in column 1 of the Object optional properties table. If the property is not one of these strings the call is ignored.

val: various types - The new value for the property. The value must be of an appropriate type and fall within the useful range of values for the property, otherwise the call is ignored and the current value remains unaltered.

dup

Syntax:

var newObj = obj.dup();

Description:

dup creates a new object of the same type as 'obj' and copies all the properties and methods from the original into the new object. The properties are copies of the values not references to the original. This method is useful a useful shortcut when creating complex objects made from similar components.

Parameters:

none.

translate

Syntax:

obj.translate(x, y);

Description:

Applies a translate matrix to obj's transform matrix which effectively moves the object by adding offsets of 'x' and 'y' to the drawing origin the of the object.

These transforms are applied in insertion order. They are not permanent, the net transform is applied when the object is rendered and then the transform matrix reset to the identity matrix.

Parameters:

x, y: Numbers - The distance in the X and Y directions respectively that the object will be moved relative to the world coordinate origin.

rotate

Syntax:

obj.rotate(degs);

Description:

Applies a rotate matrix to obj's transform matrix which rotates the object by 'deg' degrees centered on the world coordinates drawing origin (0,0).

These transforms are applied in insertion order. They are not permanent, the net transform is applied when the object is rendered and then the transform matrix reset to the identity matrix.

Parameters:

degs: Number - The angle of rotation measured in degrees counter-clockwise for RHC coordinate grids and clockwise for SVG coordinate grids.

scale

Syntax:

obj.scale(xScale[, yScale]);

Description:

Applies a scale matrix to obj's transform matrix which scales the X dimensions of the object by a factor 'xScale' and if yScale is defined, scales the Y dimensions by 'yScale'. If yScale is undefined then the Y dimensions are scaled by xScale ie. isotropic scaling. The object's dimensions enlarge or contract relative to the world coordinate origin (0,0).

These transforms are applied in insertion order. They are not permanent, the net transform is applied when the object is rendered and then the transform matrix reset to the identity matrix.

If obj.lineWidthWC is defined then the line width of a Path or the width of any border on other objects will be scaled by 'xScale'. If the lineWidthWC is undefined then the line width is set by the lineWidth property (in pixels) will remain unaffected by this scale method.

Parameters:

xScale: Number - A number by which the object's X dimensions are scaled, negative numbers will flip the object horizontally if the num.

yScale: Number - (optional) A number by which the object's Y dimensions are scaled, negative numbers will flip the object vertically.

skew

Syntax:

obj.skew(degH, degV);

Description:

Applies a skew matrix to obj's transform matrix which distorts the shape of the Obj2D by offsetting the outline X coordinates progressively at an angle of 'degH', and progressively offsetting the Y coordinates at an angle of 'degV'.

These transforms are applied in insertion order. They are not permanent, the net transform is applied when the object is rendered and then the transform matrix reset to the identity matrix.

Parameters:

degH: Number - Skew angle of rotation measured in degrees counter-clockwise from the Y axis for RHC coordinate grids and clockwise for SVG coordinate grids.

degV: Number - Skew angle of rotation measured in degrees counter-clockwise from the X axis for RHC coordinate grids and clockwise for SVG coordinate grids.

enableDrag

Syntax:

obj.enableDrag(grabCallback, dragCallback, dropCallback);

Description:

This method creates an object type Drag2D which is assigned to the obj.dragNdrop property. Drag2D objects encapsulate the event handlers that run when mousedown, mousemove and mouseup events occur within the outline of the Path as drawn on the canvas. The event handlers call the user defined callback functions passed to 'enableDrag'. 'grabCallback' is called on a mousedown events, 'dragCallback' and 'dropCallback' functions are called on subsequent mousemove and mouseup or mouseout events. The current cursor location is passed to the callback functions as an object with properties 'x' and 'y' holding the cursor coordinates measured in world coordinates. The obj will have drag and drop capability enabled whenever it is rendered to the canvas.

To simplify writing grab, drag and drop functions, the callbacks are executed in the scope of a Drag2D object which has properties to supply these values. All the handy properties in scope of the handlers are listed in the Drag2D section below.

When drag-n-drop is enabled on 'obj' the canvas mousedown event listener is armed to check for mousedown events within its outline. As long as the obj.dragNdrop property is not 'null', the mousedown listener is activated every time 'obj' is rendered to the canvas. The drag-n-drop is de-activated if the canvas is cleared by a call to cgo.clearCanvas, or by calling the obj.disableDrag method.

Parameters:

grabCallback: Function or null - This function to be called when a 'mousedown' event occurs within the outline of 'obj'. An object containing the current cursor 'x' and 'y' world coordinate position as properties is the only parameter passed when the function is called.

dragCallback: Function or null - This function to be called when a 'mousemove' event occurs after the mouse down event has occurred with the outline of 'obj'. An object containing the current cursor 'x' and 'y' world coordinate position as properties is the only parameter passed when the function is called.

dropCallback: Function or null - This function to be called when a mouseup or mouseout event occurs after the mouse down event. An object containing the current cursor 'x' and 'y' world coordinate position as properties is the only parameter passed when the function is called.

disableDrag

Syntax:

obj.disableDrag();

Description:

Sets the obj.dragNdrop property to 'null' and removes the reference to obj from the array of Obj2D to be checked for a hit on mousedown events.

Parameters:

none

Object optional properties

The following table sets out all the supported object properties that may be set as key-value pairs passed to the constructor or set individually after construction using the 'setProperty' method.

Property NameTypeRange / DescriptionPathShapeImgTextClipMask
x Number
(World Coords)
The offset along the X axis by which the object is moved relative to its drawing origin which remains at (0, 0). This is a permanent offset not reset after rendering.
y Number
(World Coords)
The offset along the Y axis by which the object is moved relative to its drawing origin which remains at (0, 0). This is a permanent offset not reset after rendering.
rotNumber (deg)The angle by which the object its drawing origin which remains at (0, 0). This is a permanent rotation not reset after rendering.
sclNumber
(non zero)
The scaling factor by which the objects dimensions are scaled, the expansion or contraction is centered on the object's drawing origin (0, 0). This is a permanent change in size not reset after rendering.
skewX Number (deg) The angle by which the object's coordinates are skewed relative to the Y axis. This is a permanent skewing of coordinates not reset after rendering.
skewY Number (deg) The angle by which the object's coordinates are skewed relative to the X axis. This is a permanent skewing of coordinates not reset after rendering.
strokeColorCSS Colorsee Colors
fillColorCSS Colorsee Colors
fillRuleString"nonzero" or "evenodd". Species how Shapes within Shapes will be filled.
lineWidthWCNumber
(World Coords)
A number >0 specifying the width of the line used to stroke Paths and draw borders around Shapes.
lineWidthNumber (pixels)A number >0 specifying the width of the line used to stroke Paths and draw borders around Shapes.
lineCapString'butt', 'round', 'square'. Specifies the style of junction at Path segment joins and Shape border corners.
isoBoolean or Stringtrue, 'iso' or 'isotropic' will preserve the aspect ratio of a Path in non-isotropic coordinates.
false will allow independent X and Y scaling.
Path default iso value is false.
dashedArray[mark, space ...] the repeating mark-space pixel lengths
dashOffsetNumber (pixels)The length of initial space before the first dash
borderBooleantrue or falsy
shadowOffsetXNumber
(World Coords)
The distance by which the shadow of the object is displaced along the X axis
shadowOffsetYNumber
(World Coords)
The distance by which the shadow of the object is displaced along the Y axis
shadowBlurNumber
(World Coords)
The radius of blurring of the edge of the object's shadow.
shadowColorCSS Colorsee Colors
fontSizeNumberFont size in Pixels
fontWeightNumberFont weight 100..900
fontFamilyStringFont Family in HTML font name format
bgFillColorCSS ColorIf set Text will be rendered as box text with background filled with 'bgFillColor' color
imgWidthNumber
(World Coords)
Width of an Img object. Aspect ratio is maintained if imgHeight is not set.
imgHeightNumber
(World Coords)
Height of an Img object. Aspect ratio is maintained if imgWidth is not set.
lorgNumber[1,2, ... 9] Specifies the location of the drawing origin in an Img or Text object.
1=upper-left, 2=upper-mid, ... 9=lower-right

Notes

Preserving Aspect Ratio

The Cango graphics context allows independent X and Y axis world coordinate scaling. Different X and Y scaling never distorts text or images and applications usually want Shapes to have their aspect ratio preserved. But plotting a graph uses a Path object to hold the data and the X and Y coordinates are usually required vastly different scaling. To give complete control of the aspect ratio Path, Shape and ClipMask objects have an 'iso' property. Setting the obj.iso property to true will ensure that the aspect ratio is preserved independent of differing X and Y world coordinates (X axis scaling is used for both X and Y coordinates). Setting obj.iso false will allow different X and Y world coordinate scaling to be applied when rendered. By default Shape, ClipMask, Text and Img objects have 'iso' set true and Path objects have iso set false.

Object Drawing origin

All Obj2D dimensions are expressed in world coordinates referenced to the drawing origin (0,0). If no obj.translate(x, y) transform is applied the object will be rendered with its 'drawing origin' at the world coordinate origin (0,0). If a obj.translate(x, y) method is applied then the object is drawn with its drawing origin positioned at (x,y).

Text and Img objects' drawing origin is determined by the object's lorg (locate origin) property. The 'lorg' property can take values from 1..9, where 1=top left, 2=top center, and so on to 9=bottom right. When a obj.translate(x,y) is applied then it is this point that is positioned at (x,y). The lorg value of an Img or Text object can be set by the constructor's 'options' parameter or by using the obj.setProperty method.

Drop shadows

Any Cango object may be drawn with a drop shadow. All objects support drop shadows defined by properties shadowOffsetX, shadowOffsetY, shadowBlur and shadowColor. By default the shadow dimensions are set to 0 so no shadow is drawn. All dimensions are measured in world coordinates. The drop shadow properties can be set by assigning key-value pairs to the constructor's 'options' parameter or by using the obj.setProperty method. Drop shadow dimension only scale with world coordinate changes (eg. zoom and pan) they are not altered by obj.scale.

Borders

Any Shape, Text or Img object will be drawn with a border if the obj.border property is set true. The color of the border are set by strokeColor property. The width of the border is determined by the objects line width when rendered.

Line width

A Path object's outline and the border width of other object types is drawn with line width set by either the obj.lineWidthWC property which sets line width in world coordinate units or the obj.lineWidth property which sets line width in pixel units. The different methods behave differently when the object is scaled.

If a value is assigned to the lineWidthWC property, the line width or border width will scale just like any other dimension of the object with all four scaling methods. If the lineWidthWC property is null or undefined and a value has been assigned to the lineWidth property then Path outline or Shape, Image and Text borders width will have this fixed pixel value regardless of any type of scaling applied to the path or object.

If both properties have been assigned a value then the lineWidthWC takes precedence. If neither has been specified, then the current Cango property default value of lineWidth (pixel value) is used. This default value may be changed with the Cango.setPropertyDefault method.

Img definition

The Img 'descriptor' may be a string specifying an image file URL, a pre-loaded HTML Image object or an HTML Canvas element as a parameter. If the URL is passed then the image is loaded into an HTML Image object and properties describing how it is to be drawn are stored ready to be rendered onto the canvas.

Example

const jane = new Img("Images/JaneAvril.jpg", {
  imgHeight: 100,
  lorg: 2,
  border: true,
  lineWidth: 4,
  strokeColor: "red" });

The code above will initiate the loading of the file "Images/JaneAvril.jpg" from the current base URL. When the load completes the image will be available for rendering to the canvas. When rendered 'jane' object will be drawn 100 world coordinate units wide with aspect ratio preserved. It will be given a red border 4 pixels wide. When rendered the image drawing origin will be the center-top of the image (lorg=2). This drawing origin point will be rendered at the world coordinate origin (0,0) unless jane.translate(x,y) method is called prior to rendering in which case the image center-top will be placed at (x,y).

ClipMask details

The ClipMask object defines a closed shape on the canvas where drawing outside this shape is clipped. To apply a clip mask the ClipMask object must be a child of a Group, only children of the Group that are drawn after the ClipMask is rendered will be clipped. The order of adding objects to a Group determines which 'children' objects will be clipped. Child objects added to a Group before the ClipMask object are not clipped, those added after are clipped.

The canvas clipping path is automatically reset to the full canvas (ie. no clipping) by the render method after all children of the Group are rendered. The clipping path may be manually reset by adding a blank ClipMask to the Group, all objects added to the Group after a blank ClipMask will not be clipped. A blank ClipMask is created by calling the ClipMask constructor with no 'descriptor' parameter as follows:

    var blankClip = new ClipMask();
  

ClipMask Example

Figure 1 shows an example of using a ClipMask. A Group is created comprising a red square SHAPE, a circular ClipMask and a blue triangle. The square is rendered first and is not clipped, the ClipMask circle is then rendered which sets up the clipping path and then the triangle is rendered. Only the part of the triangle within the clipping path is drawn. The clipping path will be reset to the full canvas (ie. no clipping) after the triangle is rendered.

A ClipMask example.

function testClip(cvsID)
{
  const clipper = new ClipMask(circle(50)),
        sqr = new Shape(square(70), {fillColor: "red"}),
        tri = new Shape(triangle(70), {fillColor:"blue"}),
        grp = new Group(sqr, clipper, tri);

  const g = new Cango(cvsID);
  g.setWorldCoordsRHC(-60, -60, 120);
  g.render(grp);
}

Groups

Cango provides the Group object to enable multiple Obj2D and Group to be treated as a single entity for transformations and rendering to the canvas. Since other Groups can be added to a group, it provides the mechanism for inheritance of any transforms applied to parent groups.

Group constructor

Syntax:

var obj = new Group(...);

Description:

Creates a Group object with a 'children' property which holds an array of Obj2D or other Group objects. The Group object has methods to apply transforms to children, and recursively apply them to the children of child Groups. The objects forming the Group's children may be passed as parameters, either individual Obj2D or Groups or arrays of either. More objects can be added to the group after creation, by using the addObj method.

Parameters:

. . .   :Obj2D, Group or arrays or either - The 'arguments' property is parsed to extract all Obj2D and Groups and they are added to the grp.children array in sequence left to right.

Group methods

addObj

addObj

Syntax:

grp.addObj(...);

Description:

The method adds Obj2D or Group to grp. The arguments can be single Obj2D or Group or nested arrays of either. Any array structure is discarded and the individual Obj2D or Groups are added to the grp.children array. If the Obj2D or Group to be added is a child of another Group, then it is deleted from the previous Group and 'grp' becomes its new parent. If objects of the same construction are to be added to multiple Groups then duplicates should be made using the objects "dup" method and a duplicate added to each of the multiple Groups.

Parameters:

. . .   : Path, Shape, Img, Text, ClipMask, Group objects or arrays of these - The 'arguments' property is parsed to extract all Obj2D and Group and they are added to the grp.children array.

deleteObj

deleteObj

Syntax:

grp.deleteObj(obj);

Description:

If 'obj' is a child of the Group 'grp' then it is removed from the array of children.

Parameters:

obj: Obj2D or Group - The child to be removed from the Group.

translate

Syntax:

grp.translate(x, y);

Description:

Applies a translate matrix to grp's transform matrix which will move all the descendent Obj2D by the offsets of 'x' and 'y'. Transforms are applied in the order of insertion. The transform matrix is inherited by children of the Group and applied recursively to the descendent Obj2D when they are rendered to the canvas. These transforms do not change the child Obj2D definitions, the transform matrix is reset to the identity matrix after the descendent Obj2D are rendered.

Parameters:

x, y: Numbers - The distance in the X and Y directions respectively that the group will be moved relative to the world coordinate origin.

rotate

Syntax:

grp.rotate(degs);

Description:

Applies a rotate matrix to grp's transform matrix which effectively rotates all the Group's descendent children by 'deg' degrees centered on world coordinate drawing origin. Transforms are applied in the order of insertion. The transform matrix is inherited by children of the Group and applied recursively to the descendent Obj2D when they are rendered to the canvas. These transforms do not change the child Obj2D definitions, the transform matrix is reset to the identity matrix after the descendent Obj2D are rendered.

Parameters:

degs: Number - The angle of rotation measured in degrees positive anti-clockwise in RHC coordinate grids and clockwise in SVG coordinate grids.

scale

Syntax:

grp.scale(xScale[, yScale]);

Description:

Applies a scale matrix to grp's transform matrix which effectively scales the X dimensions of the Group's descendent Obj2D by a factor 'xScale' and if yScale is defined, scales the Y dimensions by 'yScale'. Transforms are applied in the order of insertion. The transform matrix is inherited by children of the Group and applied recursively to the descendent Obj2D when they are rendered to the canvas. These transforms do not change the child Obj2D definitions, the transform matrix is reset to the identity matrix after the descendent Obj2D are rendered.

If yScale is undefined then the Y dimensions are scaled by xScale ie. isotropic scaling. The descendent object's dimensions enlarge or contract relative to the world coordinate drawing origin.

If descendent Obj2D border property is set 'true' and obj.lineWidthWC is defined then the width of the border will be scaled by 'xScale'. If the lineWidthWC is undefined then the width used for the border will remain unaffected by this scale method.

Note scaling by (-1, 1) flips the group's descendent Obj2D horizontally and scaling by (1, -1) flips the objects vertically.

Parameters:

xScale: Number - A number by which descendent Obj2D X dimensions are scaled, negative numbers will flip the objects horizontally if the num.

yScale: Number - (optional) A number by which descendent Obj2D Y dimensions are scaled, negative numbers will flip the objects vertically.

skew

Syntax:

grp.skew(degH, degV);

Description:

Applies a skew matrix to Group's transform matrix which when inherited by the descendent Obj2D at render time, distorts the shape of the Obj2D by offsetting the outline X coordinates progressively at an angle of 'degH', and progressively offsetting the Y coordinates at an angle of 'degV'.

The transform matrix is applied recursively to the descendent Obj2D of the group when they are rendered to the canvas. These transforms do not change the child Obj2D definitions, the transform matrix is reset to the identity matrix after the descendent Obj2D are rendered.

Parameters:

degH: Number - Horizontal skew angle measured in degrees counter-clockwise from the Y axis for RHC grids and clockwise for SVG grids.

degV: Numbers - Vertical skew angle measured in degrees counter-clockwise from the X axis for RHC grids and clockwise for SVG grids.

setProperty

setProperty

Syntax:

grp.setProperty(propertyName, value);

Description:

Calls the setProperty method on all grp's children recursively. The 'propertyName' and 'value' arguments are passed on unaltered.

Parameters:

propertyName: String - The property to have its value set. The string is not case sensitive and may take the values set out in column 1 of the Object optional properties table. If the property is not one of these strings the call is ignored.

val: various types - The new value for the property. The value must be of an appropriate type and fall within the useful range of values for the property, otherwise the call is ignored and the current value remains unaltered.

enableDrag

Syntax:

grp.enableDrag(grabCallback, dragCallback, dropCallback);

Description:

Calls the enableDrag method on all grp's children recursively. The three user defined call back functions 'grabCallback', 'dragCallback', 'dropCallback' are passed to each child's 'enableDrag' method.

Parameters:

grabCallback:Function or null - This function to be called when a 'mousedown' event occurs within the outline of the grp's descendent object. An object containing the current cursor 'x' and 'y' world coordinate position as properties is the only parameter passed when the function is called.

dragCallback:Function or null - This function to be called when a 'mousemove' event occurs after the mouse down event has occurred with the outline of the grp's descendent object. An object containing the current cursor 'x' and 'y' world coordinate position as properties is the only parameter passed when the function is called.

dropCallback:Function or null - This function to be called when a mouseup or mouseout event occurs after the mouse down event. An object containing the current cursor 'x' and 'y' world coordinate position as properties is the only parameter passed when the function is called.

disableDrag

Syntax:

grp.disableDrag();

Description:

Sets the grp.dragNdrop property to 'null' and removes the reference to grp's children from the array of Obj2D to be checked for a hit on mousedown events.

Parameters:

none

Group properties

Property NameTypeRange / Description
childrenArrayHolds the Groups's Obj2D or Group objects in the order in which they were added.

Rendering

Cango has only one method to actually draw objects onto the canvas: cgo.render.

render takes a Group or a single Obj2D and renders it to the canvas. In the case of Group, the entire family of descendant Obj2D is rendered. Group transforms propagate down the descendent tree structure and are applied to the descendent Obj2D along with any transforms applied to the Obj2D directly. render takes a second, optional 'clear' parameter which if true will cause the canvas to be cleared of all previous drawing prior to rendering the objects.

After an Obj2D is rendered the transform matrix applied to the Obj2D is reset to the identity matrix. After a Group is rendered the transform matrix for the whole family tree are reset recursively.

After all the children of a Group have been rendered any clipMasks that has been applied will be reset to the full canvas. ClipMasks only clip drawing of Obj2D within a Group and only those added to the Group after the ClipMask was added.

render

Syntax:

cgo.render(rootobj, clear);

Description:

Renders an Obj2D or all the descendent Obj2D of a Group onto the canvas. If the 'rootobj' is a single Ob2D its transform matrix is applied along with all optional style properties and then rendered. If the 'rootobj' is a Group its transform matrix is applied to all its descendent children recursively, the descendent Obj2D are then rendered.

Parameters:

rootobj: Obj2D or Group - The Obj2D or root Group of a family tree of objects to be rendered to the canvas.

clear: Boolean - (optional) If 'clear' evaluates to 'true', the canvas is cleared before rendering, if undefined or evaluating to 'false', the canvas is not cleared and the objects being rendered are added to any existing drawing.

Drag-and-Drop

Drag-n-drop can be enabled on any Obj2D or Group by calling the obj.enableDrag method passing as parameters the event handlers to be called when mousedown, mousemove and mouseup events occur. Drag-and-Drop can be disabled by calling the obj.disableDrag or by clearing the canvas on which the object was drawn.

Drag2D Object

The 'enableDrag' method creates a object type Drag2D which is assigned to the obj.dragNdrop property. Drag2D objects encapsulate the event handlers that run when mousedown, mousemove and mouseup events occur within the outline of the Obj2D as drawn on the canvas. Initially only the mousedown event is listened for, when one occurs the handler enables listening for mousemove, mouseup and mouseout events, it then updates the values the Drag2D properties and calls the user defined 'grabHandler' callback. Subsequent mousemove events will similarly update the Drag2D properties and call the user defined 'dragHandler'. The 'dropHandler' callback is called when either a mouseup event occurs or the cursor moves off the object generating a mouseout event. The callbacks are passed the current position of the cursor on the canvas in world coordinates. The callback functions are executed in the scope of the obj.dragNdrop object.

Enabling drag-n-drop on a Group recursively enables the drag-n-drop on all the group's descendent Obj2D.

Drag2D properties

The obj.dragNdrop is a Drag2D object which has as properties several variables often required when writing event handlers, such as 'grabCrsPos', the X and Y coordinates of the cursor when the mousedown event occurred in world coordinates. The callbacks are executed in the scope of the obj.dragNdrop, 'this' will refer to the Drag2D object so its properties listed below will be available:

PropertyTypeDescription
cgo Cango objectThe Cango instance that rendered the Obj2D handling the grab event. This makes the Cango methods such as this.cgo.clearCanvas() readily accessible from the scope of the Drag2D object.
target Obj2DObj2D that received the grab event (cursor click). The grab, drag and drop functions passed to this Obj2D by its enableDrag method will be those called.
grabDwgOrg ObjectObject with 'x' and 'y' properties holding the 'as rendered' coordinates of the drawing origin (measured in world coordinates) of the target Obj2D.
grabOfs ObjectObject with 'x' and 'y' properties that are the respective offsets of the cursor coordinates from the target drawing origin at the time of the grab event, measured in world coordinates. This is simply the object:
{x:this.grabCrsPos.x - this.grabDwgOrg.x, 
 y:this.grabCrsPos.y - this.grabDwgOrg.y}
This is very often the only calculation that needs to be done in the 'grab' handler so it has been provided as a short cut that can be used in drag handlers and no grab handler is required ('null' should be passed when enableDrag is called).
grabCsrPos ObjectObject with 'x' and 'y' properties holding the cursor coordinates at grab time, measured in world coordinates.

Example 1

As an example of the drag-n-drop method, here is the code that simply drags an object with the cursor:

Figure 4a. Simple drag and drop example.

function dragBox(cvsID)
{
  const boxOutline = ['M', 0, 0, 'l', 40, 0, 0, 100, -40, 0, 'z'],
        box = new Shape(boxOutline, {
          fillColor:'orange',
          border:true,
          strokeColor:"brown"});

  function dragObj(mousePos)
  {
    const wPosX = mousePos.x - this.grabOfs.x,
          wPosY = mousePos.y - this.grabOfs.y;

    box.translate(wPosX, wPosY);
    g.render(this.target, true);    // true => clear canvas
  }

  const g = new Cango(cvsID);
  g.setWorldCoordsRHC(-100, -100, 400);

  box.enableDrag(null, dragObj, null);
  g.render(box);
}

Example 2

Here is an example of the drag-n-drop method, here is the code to rotate a knob and pointer Group:

Figure 4b. Drag and drop rotation example.

function simpleKnob(cvsID)
{
  const ptrCmds = ['M', 1.2, 0, 'L', 2.5, 0], 
        ptr = new Path(ptrCmds, {lineWidth:8}), 
        base = new Shape(circle(5), {
          fillColor:'gold',
          border: true,
          strokeColor:'gray',
          lineWidth: 2,
          shadowOffsetX:0.1,
          shadowOffsetY:-0.2,
          shadowBlur:0.1,
          shadowColor:"#303030" }),
        knob = new Group(base, ptr);
  let grabOfsAng = 0,
      angle = 0;

  function knobGrab(mousePos)
  {
    const csrX = mousePos.x - this.grabDwgOrg.x,
          csrY = mousePos.y - this.grabDwgOrg.y;
    grabOfsAng = Math.atan2(csrY, csrX) - angle;
  }

  function knobDrag(mousePos)
  {
    const csrX = mousePos.x - this.grabDwgOrg.x,
          csrY = mousePos.y - this.grabDwgOrg.y;

    angle = Math.atan2(csrY, csrX) - grabOfsAng;
    knob.rotate(180*angle/Math.PI);
    gc.render(knob, true);
  }

  const gc = new Cango(cvsID);
  gc.setWorldCoordsRHC(-5, -5, 10);   // isotropic coords
  // enable Drag and Drop on the knob
  knob.enableDrag(knobGrab, knobDrag, null);
  gc.render(knob);
}

SVG data syntax

The outlines for Path, Shape and ClipMask objects can be defined by a string or array containing SVG path data format. The path is defined as a series of segments each comprises a single letter command such as 'M' for move, 'L' for a line segment, 'C' for a cubic Bezier curve, etc and 'Z' for a close path instruction. the commands are followed by their associated coordinates.

Commands are case sensitive, uppercase command coordinates are interpreted as absolute i.e. measured from the world coordinate origin (0,0). Lowercase command coordinates are interpreted as being relative to the current pen position i.e. the end point of previous command. The SVG standard requires the first command must always be a move command ('M') followed by the x, y values of the starting point of the path in world coordinates. This is followed by an arbitrarily long set of segments comprising a command and its associated parameters and coordinates.

In Left Handed Cartesian coordinate systems, the SVG standard, the segment coordinates are interpreted as having Y coordinate values increase DOWN the canvas and angles increase clockwise. In Right Handed Cartesian coordinate systems, coordinates are interpreted as having Y values increase UP the canvas and angles increase counter-clockwise.

SVG path data syntax details

Command
Parameters
Description
M
x,y
moveto: Moves the pen to a new location. No line is drawn. All path data must begin with a 'moveto' command.
Line Commands
L
x,y
lineto: Draws a line from the current point to the point (x,y).
H
x
horizontal lineto: Draws a horizontal line from the current point to x.
V
y
vertical lineto: Draws a vertical line from the current point to y.
Cubic Bezier Curve Commands
C
x1 y1 x2 y2 x y
curveto: Draw a cubic Bezier curve to the point (x,y) where the points (x1,y1) and (x2,y2) are the start and end control points, respectively.
S
x2 y2 x y
shorthand/smooth curveto: Draw a curve to the point (x,y) where the point (x2,y2) is the end control point and the start control point is the reflection of the last point's end control point.
Quadratic Bezier Curve Commands
Q
x1 y1 x y
quadratic Bezier curveto: Draw a quadratic Bezier between the last point and point (x,y) using the point (x1,y1) as the control point.
T
x y
shorthand/smooth quadratic Bezier curveto: Draw a quadratic Bezier between the last point and point (x,y) using the reflection of the last control point as the control point.
Elliptical Arc Curve Commands
A
rx, ry,
x-rotation,
large-arc-flag,
sweep-flag,
x, y
elliptical arc: Draws and arc starting from the current point and ending at (x, y). The ellipse has the two radii (rx, ry). The x-axis of the ellipse is rotated by 'x-axis-rotation' relative to the x-axis of the world coordinate system. The 'large-arc-flag' and the 'sweep-flag' together define which way the arc joins to start and end point.

In RHC coordinates the 'x-axis-rotation' is positive anti-clockwise and 'sweep-flag = 1' is interpreted as the arc sweeping in an anti-clockwise direction.

In Left Hand Cartesian, SVG standard coordinate systems the 'x-axis-rotation' as positive clockwise and 'sweep-flag = 1' flag is interpreted as the arc sweeping in a clockwise direction.
End Path Commands
Z
-
closepath: Closes the path. A line is drawn from the last point to the first.

Relative coordinates:

To use path end point and control point coordinates relative to the last pen position use a lowercase letter for the command, eg. 'a' rather than 'A'.

As an example, here is the array of commands to draw a unit square with the drawing origin (0,0) at its center.

var cgoSquare = ['M', 0.5,-0.5, 'l',0,1, -1,0, 0,-1, 'z'];
var svgSquare = "M 0.5 -0.5 l 0 1 -1 0 0 -1 z";

Numerical path data

Cango allows a concession to the SVG command format, by accepting an array of data values with no command strings as a valid path definition. The numbers are considered as a series of x,y coordinate pairs. The initial 'M' command to move to the location of the first x,y pair is assumed, and the succeeding pairs are assumed to be preceded by an 'L' command. An example of storing coordinates values in this format:

  ...
  const data = [];
  for (let i=0; i<n; i++)
  {
    data.push(xFn(i), yFn(i)); // xFn producing x values, yFn producing y values
  }
  g.drawPath(data);   // draw line starting at data[0],data[1] then n-1 straight line segments

lorg (locate origin)

Location of the drawing origin within the bounding box of a Text or Img object is set by the parameter 'lorg'. The 'lorg' property can take integer values 1..9, lorg>=1 locates the top,left of the text box or image at the (x, y) position, lorg=2 locates the top, center of the box at the (x, y) position, and so on. Fig. 5 shows the effect of each 'lorg' value on where a text object is drawn. Each text object in the figure is drawn at the x,y coordinates of the adjacent grid intersection, the text string itself specifies which lorg value was used when drawing the text.

Figure 5. Examples of the 9 possible values of lorg. Each label states its lorg value. Each label is drawn at the coordinates of its nearest grid intersection. The red labels demonstrate that the lorg position is also the center of rotation.


Colors:

The 'fillColor' or 'strokeColor' parameters of Cango objects may be specified either by a string representing the color in one of the CSS color formats or by a reference to a LinearGradient and RadialGradient object.

CSS Color formats

There are five different formats that can be used to define a color for use in the canvas:
- 6 Digit RGB hex notation, '#rrggbb', where 'rr' sets the Red level (00 to ff), 'gg' sets the Green and 'bb' sets the Blue level.
- 3 Digit RGB hex notation '#rgb', this is converted into six-digit form (#rrggbb) by replicating digits, not by adding zeros. For example, #fb0 expands to #ffbb00. - RGBA notation 'rgba(r, g, b, a)' where r, g and b are decimal numbers in the range 0 to 255 representing the Red, Green and Blue levels respectively and a is the Alpha or transparency value, 0 being fully transparent and 1.0 fully opaque.
- RGB notation "rgb(r, g, b)" where r, g and b are decimal numbers in the range 0 to 255 representing the red, green and blue levels respectively. This is a suitable format for entering dynamic color values. The calculated r, g and b values may be passed to drawing methods by the string 'rgb('+r+','+g+','+b+')'.
- Predefined colors names specified by the Extended CSS Color List eg. 'red', 'blue', 'maroon', 'palegoldenrod', 'wheat' etc. There are 143 standard colors named in the list.

LinearGradient and RadialGradient Objects

The LinearGradient and RadialGradient objects encapsulates the instructions from making canvasGradient objects just as if ctx.createLinearGradient or ctx.createRadialGradient had been called. The difference is that they expect the coordinates passed as parameters to be in world coordinates not pixels. If the 'fillColor' or 'strokeColor' property of an object is assigned to be a LinearGradient or RadialGradient object then the coordinates defining the gradient are relative to the drawing origin of the object, so if the object is translated then the gradient fill will move with the object. The LinearGradient fill will also scale and rotate with the object

The LinearGradient and RadialGradient constructors are global and are independent of any particular Cango instance.

LinearGradient or RadialGradient objects may be used as the fill color for cgo.clearCanvas methods. The world coordinates passed to the constructor are relative to the current world coordinate drawing origin 0,0.

Example 1:

An example of the LinearGradient is:

var gradObj = new LinearGradient(-2,2, 2,-2);
gradObj.addColorStop(0, 'yellow');
gradObj.addColorStop(0.5, 'green');
gradObj.addColorStop(1, 'black');

g.setWorldCoordsRHC(-2, -2, 4);  // 4x4 square, 0,0 in center

g.drawShape(square(4), {fillColor:gradObj});

Example 2:

An example of the RadialGradient is :

var grad = new RadialGradient(0, 0, .5, 1, 1, 2.5);
grad.addColorStop(0, '#aabbff');
grad.addColorStop(1, '#00f');

g.setWorldCoordsRHC(-2, -2, 4);  // 4x4 square, 0,0 in center

g.drawShape(square(4), {fillColor:grad});

.


Zoom and Pan Utility

Support for zoom and pan of Cango drawings is provided by the global function initZoomPan. This function should be called after any canvas drawing layers have been created ensuring that the zoom and pan controls will be on the top layer of the stack and thus giving priority to then for any mouse click events. The function draws a semi-transparent set of controls in the top right corner of the canvas. When these control arrows are clicked the Cango contexts nominated will have their world coordinates modified to zoom or pan the canvas drawing.

initZoomPan

Syntax:

initZoomPan(zpLayerId, gc, reDraw);

Description:

This function creates an overlay canvas and draws Zoom and Pan controls in the top right corner of a canvas element with ID 'zpLayerId'. Any or all the Cango contexts defined on any of the canvases in the stack can be zoomed and panned by clicking on these controls. The Cango contexts to be affected by zooming and panning are set by the 'gc' parameter. 'gc' may be a single Cango context or an array of contexts. Clicking the zoom controls will re-scaling the world coordinates of these contexts by 20% per click. Clicking the pan controls will add or subtract 50 pixels per click to the corresponding coordinate offset. When the scaling or position offsets have been applied, the Cango drawings on the canvas must be re-drawn to show the effect. The callback function to do this re-draw is also passed as the 'reDraw' argument.

Parameters:

zpLayerId:String - This is the string ID of the canvas layer that will hold the zoom and pan control buttons. This is the ID returned from a call to Cango.createLayer() method, so a call to this method may be used in place of the string.

gc:Cango context or Array of Cango contexts - This is the Cango graphics context that will have all its drawing zoomed or panned. If several Contexts are present on the background canvas or any canvas layer they may be passed as an array of Cango contexts, all will be zoomed or panned together as the control buttons are clicked.

reDraw:Function - The user defined function 'redraw' will be called to redraw all the objects on all the canvases in their new zoomed or panned size or position.

Example:

Figure 6. Example of zoom and pan controls, click on the buttons in the top right corner to zoom or pan the drawing. Clicking on the 'X' button returns the drawing to its original size and position.

The code for the zoom and pan example in Fig. 6 is shown below. Note that the line width of the Img border is set in world coordinates using the 'lineWidthWC' property so the border scales with zooming, whereas the border width of the yellow shape is set in pixels using the 'lineWidth' property and so doesn't scale with zooming.

function zoomPanTest(cvsID)
{
  const xmin = -300, ymin = -200, xspan = 750,
    Arc3 = "M0,50 h-150 a150,150 0 1,0 150,-150 z M-25,25 v-150 a150,150 0 0,0 -150,150 z";

  const g = new Cango(cvsID);
  g.setWorldCoordsRHC(xmin, ymin, xspan);

  const gL1 = new Cango(g.createLayer());
  gL1.dupCtx(g);

  const jane = new Img("Images/JaneAvril2.jpg", {
    scl: 2,
    imgHeight: 100,
    border:true,
    lineWidthWC:6,
    strokeColor:'sienna',
    shadowOffsetX:8,
    shadowOffsetY:-8,
    shadowBlur:4,
    shadowColor:'grey' });

  const txt = new Text("Caption", {
    fillColor:"red",
    fontSize:20,
    border:true,
    lineWidth:1 });

  const arcsObj = new Shape(Arc3, {
    scl: 0.5,
    border:true,
    strokeColor:"red",
    lineWidth:2,       // pixels
    fillColor:"yellow" });

  function drawBits()
  {
    jane.translate(100, 250);
    g.render(jane, true);
    txt.translate(100, 20);
    g.render(txt);
    gL1.render(arcsObj, true);
  }

  drawBits();
  initZoomPan(g.createLayer(), [g, gL1], drawBits);
}