日期:2014-05-16  浏览次数:20388 次

JS 绘图类(纯DIV绘图)

很早之前写的一个绘图类,那时候VML和SVG的图库还不是十分流行,最初的灵感以及图形算法来自一个叫w_jsGraphics.js的类库。

用一个点来绘制出世界。甚以此纪念那段充满激情的岁月。

?

/**
 *JS 绘图类  Graphics- 0.02
 *@author  <a href="mailto: redrainyi@gmail.com">yyl</a>
 *@param canvas 画布(画布可以是 DIV(IE) 或 Layer(Netscape)
 *参考资料《w_jsGraphics.js绘图类》《DHTML手册》《BISOFT JS》《Computer Graphics》
 *CopyLeft 2007 在引用或转载时请保持文件代码的完整性
 */
function Graphics(canvas)
{
	/*获得画板以后的绘图都是在画板上实现*/
	this.canvas = typeof(canvas)=="string"?document.getElementById(canvas):canvas;
	/*默认颜色 #000000黑色*/
	this.color = '#000000';
	/*设置线默认象素为 1px*/
	this.setStroke(1);
	/*文本默认字体*/
	this.setFont('verdana,geneva,helvetica,sans-serif', 20, "PLAIN");	
	/*创建一个Div元素作为根结点 所有绘图的根结点*/
	this.documentRoot = document.createElement("div");	
}
Graphics.prototype = {
	canvas : window,
	color  : '#000000',
	stroke : 1,
	documentRoot : null,
	/*设置颜色 格式"#RRGGBB" 颜色会保留到下一次再重新设置为止*/
	setColor : function(c)
	{
		this.color = c;
	},
	/*绘制点DIV*/
	drawDiv : function(x, y, w, h)
	{
		var elem = document.createElement("div");/*创建一个Div元素*/
		elem.style.position = 'absolute';
		elem.style.overflow = 'hidden';
		elem.style.left = x;
		elem.style.top  = y;
		elem.style.width  = w;
		elem.style.height = h ;
		elem.style.backgroundColor = this.color;
		this.documentRoot.appendChild(elem);
	},
	
	/*绘制组件 (绘图)*/
	paint : function()
	{
		this.canvas.appendChild(this.documentRoot);/*将根结点添加到画布上*/
	},
	
	/*清空画板*/
	clear : function()
	{
		if (this.canvas) this.canvas.innerHTML = '';
	},
	
	/*设置画笔 参数代表点(象素)大小 默认是 1px  (设置为-1时候代表 虚点线)*/
	setStroke : function(x)
	{
		this.stroke = x;
		if (!(x+1))	/*javaScript中 0为假 */
		{	/*设置画法为虚点*/
			this.drawLine = this.drawLineDott;
			this.drawOval = this.drawOvalDott;
			this.drawRect = this.drawRectangleDott;
		}
		else if (x > 1)
		{	/*实线*/
			this.drawLine = this.drawLine2D;
			this.drawOval = this.drawOval2D;
			this.drawRect = this.drawRectangle;
		}
		else
		{
			/*/象素大小(厚度)为1px的线*/
			this.drawLine = this.drawLine1D;
			this.drawOval = this.drawOval1D;
			this.drawRect = this.drawRectangle;
		}
	},

	/*画虚线*/
	drawLineDott : function(x1, y1, x2, y2)
	{
		if (x1 > x2)
		{
			var _x2 = x2;
			var _y2 = y2;
			x2 = x1;
			y2 = y1;
			x1 = _x2;
			y1 = _y2;
		}
		var dx = x2-x1, dy = Math.abs(y2-y1),
		x = x1, y = y1,
		yIncr = (y1 > y2)? -1 : 1,
		drw = true;
		if (dx >= dy)
		{
			var pr = dy<<1,
			pru = pr - (dx<<1),
			p = pr-dx;
			while ((dx--) > 0)
			{
				if (drw) this.drawDiv(x, y, 1, 1);
				drw = !drw;
				if (p > 0)
				{
					y += yIncr;
					p += pru;
				}
				else p += pr;
				++x;
			}
			if (drw) this.drawDiv(x, y, 1, 1);
		}
		else
		{
			var pr = dx<<1,
			pru = pr - (dy<<1),
			p = pr-dy;
			while ((dy--) > 0)
			{
				if (drw) this.drawDiv(x, y, 1, 1);
				drw = !drw;
				y += yIncr;
				if (p > 0)
				{
					++x;
					p += pru;
				}
				else p += pr;
			}
			if (drw) this.drawDiv(x, y, 1, 1);
		}
	},

	/*画线(经过优化的绘线方法)*/
	drawLine2D : function(x1, y1, x2, y2)
	{
		if (x1 > x2)
		{
			var _x2 = x2;
			var _y2 = y2;
			x2 = x1;
			y2 = y1;
			x1 = _x2;
			y1 = _y2;
		}
		var dx = x2-x1, dy = Math.abs(y2-y1),
		x = x1, y = y1,
		yIncr = (y1 > y2)? -1 : 1;
	
		var s = this.stroke;
		if (dx >= dy)
		{
			if (dx > 0 && s-3 > 0)
			{
				var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
				_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
			}
			else var _s = s;
			var ad = Math.ceil(s/2);
	
			var pr = dy<<1,
			pru = pr - (dx<<1),
			p = pr-dx,
			ox = x;
			while ((dx--) > 0)
			{
				++x;
				if (p > 0)
				{
					this.drawDiv(ox, y, x-ox+ad, _s);
					y += yIncr;
					p += pru;
					ox = x;
				}
				else p += pr;
			}
			this.