MISCELLANEOUS TECHNICAL ARTICLES BY Dr A R COLLINS

Canvas 3D Graphics

Cango3D graphics library for HTML5 canvas

Cango3D is a graphics library for the HTML5 canvas element which simplifies the drawing and animation of 3D shapes on the 2D canvas. Cango3D uses the fact that straight lines and Bézier curves maintain their shape under 3D transformation. Restricting object outline definitions to these types means that smooth curves can be drawn in 3D with very few points needing to be transformed and projected onto the canvas.

Here are various examples of objects, drawn and animated by the Cango3D graphics library.

Cang3D basic drawing capability

Figure 1. Examples of drawing using the 3D graphics library.

Cango3D

Cango3D provides methods for creating, rendering and animating 3D outline paths, filled shapes and stroke text on a 2D canvas. Complex 3D objects can be constructed by maneuvering shapes, acting as panels, forming the 3D object.

The current version of Cango3D is 10v01, and the source code is available at Cango3D-10v01.js.

Features of the Cango3D

  • Simple and lightweight - Cango3D draws four object types: Path3D, Panel3D, Shape3D and Text3D. All these inherit methods from the generic Obj3D object. Objects can be grouped as children of a Group3D object. Group3D can also have more Group3Ds as children and so on to form a tree of Objects arbitrarily deep.

  • World Coordinates - Cango3D uses the Right Handed Cartesian coordinate system. The canvas sits in the XY plane, the viewpoint is at some distance along the positive Z axis (out of the screen) X values increase to the RIGHT and Y axis values increase UP the screen. The field of view is user defined. The world coordinates are also used defined, mapping of 3D world coordinates to 2D canvas pixels is handled by the Cango3D.

  • Shading - When a Shape3D are rendered their fill color is shaded according to the current position direction of the user defined light source.

  • Animation using matrix transforms - All Obj3D and Group3D have a methods translate, rotate, rotateX, rotateY, rotateZ, scale and scaleNonUniform which apply temporary transforms to the object coordinates as they are rendered. The transforms are reset after rendering, new transforms can then be applied at every frame of an animation without changing the underlying coordinates of the Obj3D. Children inherit the effect of any transforms applied to the parent recursively.

  • Drag and Drop - Any Obj3D or Group3D can be simply enabled for drag-n-drop, just specify the callback functions, all the event handling support code is built-in.

  • Tagging of Panel3D - A Panel3D may have Text or other Panel3Ds grouped so it appears they are drawn on the panel.

  • Object creation by Extrusion or Rotation - Utility functions 'objectByExtrusion3D' and 'objectByRevolution3D' are provided for easy creation of 3D objects of these styles.

Using Cango3D

Firstly, download the Cango3D JavaScript source file: Cango3D-10v01.js or the minified version Cango3D-10v01-min.js. This can be placed in the same directory as the web page HTML file. Add the following line to the web page header:

  <script src="Cango3D-10v01.js"></script>

This file exposes the global objects: Cango3D, Shape3D, Path3D, Sphere3D, Text3D and Group3D. To assist in object construction and manipulation the global Cgo3Dsegs and the 2D shape outline generator shapeDefs are also supplied along with the utility functions: svgToCgo3D, calcNormal, calcIncAngle.

Within the body of the web page, there must be a canvas element, it must have a unique id.

Typical HTML code is:

 <canvas id="canvasID" width="500" height="300"></canvas>

An instance of a Cango3D graphics context is created as follows:

 const g = new Cango3D(canvasID);

The returned object referenced by g, has the Cango3D methods such as g.setWorldCoords3D, g.clearCanvas, g.setFOV and so on.

Creating an object with Cango3D

A 3D object it is made by first creating its component pieces by calling the constructor of either Path3D, Panel3D, Shape3D or Text3D. Each constructor requires a definition parameter, an outline path expressed in 3D SVG coordinates for the Path3D and Shape3D, or expressed in 2D (XY plane) SVG coordinates for the Panel3D or a String for the Text3D. Various optional properties controlling the appearance of the object can be passed to the constructor.

Cango3D provides the global object shapeDefs to simplify defining common shapes. The shapeDefs object has methods to generate circle, ellipse, square, triangle. These methods take basic dimensions as a parameter and return an array of data in 2D SVG format defining the shape outline.

More complex objects may be created with the utilities objectByExtrusion3D and objectByRevolution3D. objectByExtrusion3D takes a flat panel in the XY plane and extrudes it to form a 3D object. objectByRevolution3D takes a 2D path in the XY plane and rotates it in steps about the Y axis to form a symmetric object.

Example

Here is a very simple example, it creates a Panel3D representing a plate using a shapeDefs.circle as its outline path and a Path3D representing a curved stick using a array of Cgo3D data defining a Cubic Bézier curve. These are then added to a Group3D to move them as one entity. The Group3D's 'rotate' method is applied with the new rotation angle prior to the Group3D being rendered every 50 msec.

JavaScript source code for this example is shown below:

function drawDemo(cvsID)
{
  const g = new Cango3D(cvsID),
        stick = new Path3D(["M",0,0,0, "C", 0,33,0, -5,66,0, -15, 100, 0], 
                      {y:-100, strokeColor:"sienna", lineWidth:3}),
        plate = new Panel3D(shapeDefs.circle(50), 
                      {xRot:-75, fillColor:"yellow", backColor:"yellow"}),
        plateNstick = new Group3D(stick, plate);
  let angle = 0;

  function turnPlate()
  {
    angle += 20;
    if (angle > 360)
      angle -= 360;

    plateNstick.rotateY(angle);  // apply matrix to Group3D
    g.render(plateNstick);
  }

  g.setWorldCoords3D(-75, -120, 150);
  g.setLightSource(0, 500, 200);

  setInterval(turnPlate, 50)        // keep doing this forever
}

Animated sculpture in 3D with draggable base

Here is an example of many of the features of Cango3D working together. The hexagonal display stand base is made by 'objectByRevolution3D' with 6 segments joined by straight lines. The turntable on the display stand has also been made from 'objectByRevolution3D' but with 36 segments joined by arcs. The sculpture is made in the style of Markus Raetz work's. It is made from a single Path3D.

The sculpture is animated using the Timeline utility controlled by the TURN, PAUSE, STEP, STOP control buttons.

The dark green base has been enabled for drag-n-drop so that the display stand can be tilted by clicking and dragging with the mouse. This allows a good view of the ingenuity of the Markus Raetz style sculpture.