JavaScript OO Vector Graphics Package | WebReference

JavaScript OO Vector Graphics Package

current pageTo page 2
[next]

JavaScript OO Vector Graphics Package

Over the years, JavaScript has developed into the browser scripting language of choice for DHTML. It has complete access to the browser’s Document Object Model (DOM) and Cascading Style Sheets (CSS). One apparent omission from JavaScript’s functionality seemed to be the ability to draw graphics directly to the browser window. When this was questioned the answer was always along the lines of “JavaScript is intended to provide DHTML in browsers and is not suited for CPU intensive operations like graphics.”

However, there are benefits when using JavaScript to create an extensible object-oriented vector-based graphics package. Some of these are:

  • JavaScript is widely supported in browsers and fairly well standardized.


  • Easy integration with other JavaScript code.


  • The JavaScript graphics is drawn in the same browser windowpane as other HTML elements. This differs from technologies such as Java and Flash where on Windows plat forms at least the output is contained within a separate windowpane and will always obscure any HTML below.
The first step in building a graphics framework is to specify the canvas (the space in which to display the graphics). For this we choose the HTML <DIV> tag, or if none specified the <BODY> tag. If using a <DIV>, it must have a style attribute specifying position to either absolute or relative. For example:
<HTML>
   <BODY>
      <DIV id=”theCanvas” style=”position:absolute; left=100px;    top=50px;”>
      </DIV>
   </BODY>
</HTML>

Now, with a canvas to render on we can start building the graphics framework. The framework must oversee interactions with the canvas providing the ability to “plot” points, and it will also hold all the attributes which will affect the drawing such as the pen color, z-index and so on.

The framework is managed by a class called “Graphics” which supports a minimal core set of functions. The constructor takes the id of the canvas or “” or null for the <BODY> and initializes the framework variables and settings.

function Graphics(canvas) 
{ 
   // the ID of the canvas DIV or “” for document.body
   this.canvas = canvas;
   // a cache of hidden DIV elements
   this.cache = new Array; 
   // the collection of displayed shapes
   this.shapes = new Object; 
   // a number used for generating internal IDs
   this.nObject = 0; 
   
   // default settings
   this.penColor = "black";
   this.zIndex = 0; 
}

Plots are implemented by creating small pixel-sized <DIV> elements contained and positioned within the parent canvas. The createPlotElement() method of the Graphics class handles this task. It first checks the reference to the canvas. If not previously retrieved, it finds it using document.getElementById(), or document.body if no ID is supplied. Next it gets a <DIV> element for the new pixel either from the cache or by creating a new one and appends it to the canvas. New <DIV> elements must have their style.position attribute set to absolute so that they may be positioned within their parent canvas. Finally, the graphics settings are applied to the plot element along with its position and size.

Graphics.prototype.createPlotElement = function(x,y,w,h) 
{
   // detect canvas
   if ( !this.oCanvas )
   {
      if ( (this.canvas == undefined) || (this.canvas == "") ) 
          this.oCanvas = document.body;
      else 
         this.oCanvas = document.getElementById(this.canvas);
   }
 // retrieve DIV
 var oDiv;
 if ( this.cache.length )
   oDiv = this.cache.pop();
 else {
   oDiv = document.createElement('div');
   this.oCanvas.appendChild(oDiv);
   oDiv.style.position = "absolute";
   oDiv.style.margin = "0px";
   oDiv.style.padding = "0px";
   oDiv.style.overflow = "hidden";
   oDiv.style.border = "0px";
 }
 // set attributes
 oDiv.style.zIndex = this.zIndex;
 oDiv.style.backgroundColor = this.penColor;
   
   oDiv.style.left = x;
   oDiv.style.top = y;
   oDiv.style.width = w + "px";
   oDiv.style.height = h + "px";
   oDiv.style.visibility = "visible";
   
   return oDiv;
}


Plot-elements are released and “un-plotted” using the releasePlotElement() method. This method simply sets the style.visibility attribute of the <DIV> element to “hidden” and places it in the cache for later reuse.

Everything drawn on the canvas must be managed by Shape objects. The “Shape” within the graphics framework is an abstract term referring to JavaScript classes that support draw() and undraw() methods. The Shape object provides a convenient handle to group plot-elements together and can be arbitrarily complex. To manage shapes within the framework we need the following two methods in the Graphics class.

Graphics.prototype.addShape = function(shape) 
{
   shape.oGraphics = this;
   shape.graphicsID = this.nObject;
   this.shapes[this.nObject] = shape;
   this.nObject++;
   shape.draw();
   return shape;
}
Graphics.prototype.removeShape = function(shape) 
{
   if ( (shape instanceof Object) && 
      (shape.oGraphics == this) && 
      (this.shapes[shape.graphicsID] == shape) ) 
   {
      shape.undraw();
      this.shapes[shape.graphicsID] = undefined;
      shape.oGraphics = undefined;
   }
}
The addShape() method sets two properties on the supplied shape object; the oGraphics property is set to the instance of the Graphics class and the graphicsID is set to a unique number. This graphicsID is used to access the shape later. Finally, the draw() method is called on the shape causing it to render itself on the canvas.

The removeShape() method checks that the supplied shape is contained within the canvas, then calls undraw() to allow the shape to release its plot-elements before clearing the it from the collection of shapes.

current pageTo page 2
[next]

Created: June 5, 2003
Revised: January 14, 2004

URL: http://webreference.com/programming/javascript/jf/1