Click here to Skip to main content
15,881,600 members
Articles / Programming Languages / Javascript

Drawing lines in Mozilla based browsers and the Internet Explorer

Rate me:
Please Sign up or sign in to vote.
4.78/5 (15 votes)
28 Nov 20068 min read 159K   1.5K   47  
Implementing the Bresenham line drawing algorithm in JavaScript to be used in browsers.
<!--------------------------------------------------------------------------->  
<!--                           INTRODUCTION                                

 The Code Project article submission template (HTML version)

Using this template will help us post your article sooner. To use, just 
follow the 3 easy steps below:
 
     1. Fill in the article description details
     2. Add links to your images and downloads
     3. Include the main article text

That's all there is to it! All formatting will be done by our submission
scripts and style sheets. 

-->  
<!--------------------------------------------------------------------------->  
<!--                        IGNORE THIS SECTION                            -->
<html>
  <head>
    <title>The Code Project    </title>
    <link type="text/css" href="http://www.codeproject.com/styles/global.css" rel="stylesheet" />
    
  
<style type="text/css">

BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt } H2,H3,H4,H5 { color: #ff9900; font-weight: bold; } H2 { font-size: 13pt; } H3 { font-size: 12pt; } H4 { font-size: 10pt; color: black; } PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; } CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; } 
</style>

<style>
#linecanvas {border: 1px solid #ff9900;background-color:#feeee0;width:100%;height:200px}
table.linetest{border: 1px solid #ff9900;font-size:5px;}
td.highlight{background-color:#ff9900;height:5px;width:5px;font-size: 3pt}
td.normal{border: 1px solid #ff9900;background-color:#ffffff;height:5px;width:5px;font-size: 3pt}
td.selected{background-color:#0000ff;height:5px;width:5px;font-size: 3pt}
</style>

<script src="graphics.js"></script>

<script>

function DrawPanel(id, xm, ym)
{
	this.pos = 0;
	this.id = id;
	this.points = new Array();
	this.drawLine = null;

	var o = document.getElementById(id);
	var t = this.table = document.createElement("table");
	
	t.className = "linetest"
	t.panel = this;
	t.ondblclick=function() {this.panel.clear();}
	for (var y = 0; y < ym; y++)
	{
		var r = t.insertRow(-1);
		for (var x = 0; x < xm; x++)
		{
			var c = r.insertCell(-1);
			c.panel = this;
			c.innerHTML = "&nbsp;";
			c.x = x; c.y = y;
			c.className = c.MynormalClass = "normal";
			c.onmouseover = function() {this.className="highlight";}
			c.onmouseout = function() {this.className=this.MynormalClass;}
			c.onclick=function() {this.panel.setPoint(this);}
			c.ondblclick=function() {this.panel.clear();}
		}
	}
	o.appendChild(t);
}
DrawPanel.prototype.clear = function()
{
	for (var y = 0; y < this.table.rows.length; y++)
	{
		var r = this.table.rows[y];
		for (var x = 0; x < r.cells.length; x++)
		{
			var c = r.cells[x];
			c.className=c.MynormalClass;
		}
	}
}
DrawPanel.prototype.setPixel = function(x, y)
{
	if (this.table.rows.length <= y) return;
	var r = this.table.rows[y];
	if (r.cells.length <= x) return;
	var c = r.cells[x];
	c.className = "selected";
}
DrawPanel.prototype.doLine = function()
{
	if (this.points.length != 2 || (this.points[0].x == this.points[1].x && this.points[0].y == this.points[1].y)) {
		alert("You must define two different points, to exactly describe the line.");
		return;
	}
	if (typeof(this.drawLine) == 'function')
		this.drawLine(this.points[0].x, this.points[0].y, this.points[1].x, this.points[1].y);
}
DrawPanel.prototype.setPoint = function(c)
{
	if (typeof(c) != "undefined") 
	{	
		if (typeof(this.points[this.pos]) != "undefined")
			this.points[this.pos].className = this.points[this.pos].MynormalClass = "normal";
			
		var p = this.points[this.pos] = c;
		this.pos++;
		this.pos = this.pos % 2;	
		c.MynormalClass = "selected";
	}
}
</script>


</head>
  <body color="#000000" bgcolor="#FFFFFF">

<h2>Illustration A</h2>
<div id="container1"></div>

<script>
var panel1 = new DrawPanel('container1', 30, 30);
panel1.drawLine = function(x1, y1, x2, y2)
{	

	if (x1 == x2 && y1 == y2) {
		setPixel(x1, y1);
		return;
	}
	var dx = x2 - x1; var sx = (dx < 0) ? -1 : 1;
	var dy = y2 - y1; var sy = (dy < 0) ? -1 : 1;
	var m = dy / dx;
	var b = y1 - m * x1;
	
	while (x1 != x2)
	{
		var y = parseInt(Math.round(m*x1 + b));
		this.setPixel(x1, y);
		x1 += sx;
	}
}
</script>
<input type="button" value="drawLine1" onclick="panel1.doLine()"/><input type="button" value="clear" onclick="panel1.clear()"/><br/>
<br/>

<h2>Illustration B</h2>
<div id="container2"></div>

<script>
var panel2 = new DrawPanel('container2', 30, 30);
panel2.drawLine = function(x1, y1, x2, y2)
{	
	if (x1 == x2 && y1 == y2) {
		setPixel(x1, y1);
		return;
	}
	var dx = x2 - x1; var sx = (dx < 0) ? -1 : 1;
	var dy = y2 - y1; var sy = (dy < 0) ? -1 : 1;
	
	if (Math.abs(dy) < Math.abs(dx))
	{	
		var m = dy / dx;
		var b = y1 - m * x1;
		
		while (x1 != x2)
		{
			this.setPixel(x1, parseInt(Math.round(m*x1 + b)));
			x1 += sx;
		}
	} 
	else 
	{
		var m = dx / dy;
		var b = x1 - m * y1;
		
		while (y1 != y2)
		{
			this.setPixel(parseInt(Math.round(m*y1 + b)), y1);
			y1 += sy;
		}	
	}
}
</script>
<input type="button" value="drawLine2" onclick="panel2.doLine()"/><input type="button" value="clear" onclick="panel2.clear()"/><br/>

<h2>Illustration C</h2>
<div id="container4"></div>

<script>
var panel4 = new DrawPanel('container4', 30, 30);
panel4.drawLine = function(x1, y1, x2, y2)
{	
	var dx = x2 - x1; var sx = 1;
	var dy = y2 - y1; var sy = 1;
	
	if (dx < 0)	{
		sx = -1;
		dx = -dx;
	}
	if (dy < 0)	{
		sy = -1;
		dy = -dy;
	}
	
	dx = dx << 1;
	dy = dy << 1;
	this.setPixel(x1, y1);
	if (dy < dx)
	{	
		var fraction = dy - (dx>>1);
		while (x1 != x2)
		{
			if (fraction >= 0)
			{
				y1 += sy;
				fraction -= dx;
			}
			fraction += dy;
			x1 += sx;
			this.setPixel(x1, y1);
		}
	} 
	else 
	{
		var fraction = dx - (dy>>1);		
		while (y1 != y2)
		{
			if (fraction >= 0)
			{
				x1 += sx;
				fraction -= dy;
			}
			fraction += dx;
			y1 += sy;
			this.setPixel(x1, y1);
		}	
	}
}
</script>
<input type="button" value="drawLine4" onclick="panel4.doLine()"/><input type="button" value="clear" onclick="panel4.clear()"/><br/>

</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Chief Technology Officer W3L
Germany Germany
-Since 1th August 2007: Chief Technology Officer of W3L
-2002/08/01-2007/07/31: PhD student
-1997/10/15-2002/07/31: Studied Electrical Engineering and Computer Science

Comments and Discussions