JavaScript 2D图形库(正在进行中)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 2D图形库(正在进行中)相关的知识,希望对你有一定的参考价值。

Object.prototype.extend = function(ns_string) { // original version from http://addyosmani.com/blog/essential-js-namespacing/
	var parts = ns_string.split('.'), parent = this, i;
	for(i=0;i<parts.length;i++) {
		if(typeof parent[parts[i]]=='undefined')
			parent[parts[i]] = {};
		parent = parent[parts[i]];
	}
	return parent;
}

if(!Object.keys) Object.keys = function(o) { // from http://tokenposts.blogspot.com.au/2012/04/javascript-objectkeys-browser.html
	if(o!==Object(o))
		throw new TypeError('Object.keys called on a non-object');
	var k = [], p;
	for (p in o) {
		if(Object.prototype.hasOwnProperty.call(o,p))
			k.push(p);
	}
	return k;
}

// draw object released into the public domain by josh atkins (2012)

var draw = {}; // use a single global variable

draw.init = function() {
	draw.extend('misc.str.clean');
	draw.extend('misc.math.pythagoras');
	draw.extend('misc.js.loadScript');
	
	// miscellaneous functions
		// str
		draw.misc.str.clean = function(strToClean) {
			return strToClean.replace(/[\.]{2,}/g, '.').replace(/\<[^\>]+?>/g, '');
		};
		
		// math
		draw.misc.math.pythagoras = function(length1, length2) {
			return Math.sqrt(Math.pow(length1, 2)+Math.pow(length2, 2));
		}
		draw.misc.math.distanceBetweenTwoPoints = function(point1, point2) {
			return this.pythagoras(Math.abs(point2.xPos-point1.xPos), Math.abs(point2.yPos-point1.yPos));
		}
		
		// js	
		draw.misc.js.loadScript = function(scriptName) {
			var newScript = document.createElement('script');
			newScript.type = 'text/javascript';
 			newScript.src = 'assets/scripts/'+this.str.clean(scriptName)+'.js';
			document.body.appendChild(newScript);
		};
	
	draw.canvas = function(id) {
		this.id = id;
		var canvasID = id;
		
		// setup the canvas <div>
		var canvasDiv = document.createElement('div');
		canvasDiv.id = id;
		canvasDiv.className = 'canvas';
		document.body.appendChild(canvasDiv);

		// setup a stylesheet for the canvas
		var canvasStyleSheet = document.createElement('style');
		canvasStyleSheet.type = 'text/css';
		document.body.appendChild(canvasStyleSheet);
		canvasStyleSheet = document.styleSheets[document.styleSheets.length-1];

		// delete the reference to the canvas <div>
		canvasDiv = null;
		delete canvasDiv;
		
		var renderPoint = function(xPos, yPos) {
			var newPoint = document.createElement('div');
			newPoint.style.left = xPos + 'px';
			newPoint.style.top = yPos + 'px';
			return newPoint;
		};
		
		var renderLine = function(startPoint, endPoint, lineDiv) {
			var tempPoint, width, height, gradient, yIntercept, distance;
			
			if(draw.misc.math.distanceBetweenTwoPoints(startPoint, {xPos: 0, yPos: 0})>draw.misc.math.distanceBetweenTwoPoints({xPos: 0, yPos: 0}, endPoint)) {
				tempPoint = startPoint;
				startPoint = endPoint;
				endPoint = tempPoint;
			}
			
			width = Math.abs(endPoint.xPos - startPoint.xPos);
			height = Math.abs(endPoint.yPos - startPoint.yPos);
			gradient = (endPoint.yPos - startPoint.yPos) / (endPoint.xPos - startPoint.xPos);
			
			yIntercept = endPoint.yPos - gradient * endPoint.xPos;
			distance = draw.misc.math.distanceBetweenTwoPoints(startPoint, endPoint);
			
			var calcXCoord = function(yPos) {
				var xPos = (yPos - yIntercept) / gradient;
				return ((gradient == Infinity) || (Math.abs(xPos) == Infinity)) ? startPoint.xPos : xPos;
			};
			var calcYCoord = function(xPos) {
				return Math.abs(gradient) == Infinity ? startPoint.yPos : gradient * xPos + yIntercept;
			};
			
			var i = 0, pointCount, switchPos = false;
			pointCount = width > height ? width : height;
			
			if(width>height) {
				if(endPoint.xPos<startPoint.xPos)
					switchPos = true;
			}
			else {
				if(endPoint.yPos<startPoint.yPos)
					switchPos = true;
			}
			
			while(i<pointCount) {
				if(width>height)
					lineDiv.appendChild(renderPoint(parseInt((switchPos?endPoint:startPoint).xPos)+i, calcYCoord(parseInt((switchPos?endPoint:startPoint).xPos)+i)));
				else
					lineDiv.appendChild(renderPoint(calcXCoord(parseInt((switchPos?endPoint:startPoint).yPos)+i), parseInt((switchPos?endPoint:startPoint).yPos)+i));
				i++;
			}
		};
		
		// define (artificial) constants
		var BORDER_STYLE = {
			DEFAULT: 1
		};

		this.pen = {
			width: 1,
			style: BORDER_STYLE.DEFAULT,
			color: '#000000'
		};
		var pen = this.pen;
		
		var shapes = function() {
			var shape, objects = {};
			
			shape = function(shapeNumber) {
				var shapeDiv = document.createElement('div'), shapeRule, ruleText;
				shapeDiv.id = 'shape'+shapeNumber;
				document.getElementById(canvasID).appendChild(shapeDiv);

				ruleText = 'background: '+pen.color+'; height: '+pen.width+'px; width: '+pen.width+'px;';

				if(canvasStyleSheet.insertRule) // NS/FF
					canvasStyleSheet.insertRule('div.canvas div#shape'+shapeNumber+' div { '+ruleText+' }');
				else if(canvasStyleSheet.addRule) // IE
					canvasStyleSheet.addRule('div.canvas div#shape'+shapeNumber+' div', ruleText);
				
				return {
					shapeRule: shapeRule,
					shapeName: 'shape' + shapeNumber,
					style: {
						border: {
							width: pen.width,
							color: pen.color,
							style: pen.style
						}
					},
					points: new (function() {
						var point, objects = {};
						
						point = function(pointNumber, xPos, yPos, linkedTo) {
							return {
								pointName: 'point' + pointNumber,
								xPos: xPos,
								yPos: yPos,
								linkedTo: linkedTo
							};
						};

						return {
							list: function() {
								for(pointObject in objects)
									alert(objects[pointObject].pointName + ': ['+objects[pointObject].xPos+', '+objects[pointObject].yPos+']');
							},
							add: function(xPos, yPos, linkedTo) {
								var newPoint = new point(Object.keys(objects).length, xPos, yPos, linkedTo);
								objects[newPoint.pointName] = newPoint;
								
								if(linkedTo)
									renderLine(newPoint, linkedTo, shapeDiv);
								
								return newPoint;
							},
							remove: function(pointOrName) {
								var pointToRemove;
								
								if(typeof pointOrName == 'string')
									pointToRemove = pointOrName;
								else
									pointToRemove = pointOrName.pointName;
								
								delete objects[pointToRemove];
								delete pointToRemove;
							}
						};
					})
				};
			};
			
			return {
				list: function() {
					for(shapeObject in objects)
						alert(objects[shapeObject].shapeName);
				},
				add: function() {
					var newShape = new shape(Object.keys(objects).length);
					objects[newShape.shapeName] = newShape;
					
					return newShape;
				},
				remove: function(shapeOrName) {
					var shapeToRemove;
					
					if(typeof shapeOrName == 'string')
						shapeToRemove = shapeOrName;
					else
						shapeToRemove = shapeOrName.shapeName;

					// delete the stylesheet rule
					
					delete objects[shapeToRemove];
					delete shapeToRemove;
				}
			};
		};
		this.shapes = new shapes;
		shapes = this.shapes;
		
		this.scribbling = {
			currentScribble: null,
			previousPoint: null,
			begin: function() {
				this.enabled = true;
				this.currentScribble = shapes.add();
				return false;
			},
			scribble: function() {
 				if(this.enabled)
					this.previousPoint = this.currentScribble.points.add((event.pageX - 16) || (event.clientX - 16), (event.pageY - 16) || (event.clientY - 16), this.previousPoint);
			},
			end: function() {
				this.currentScribble = null;
				this.previousPoint = null;
				this.enabled = false;
				return false;
			},
			enabled: false
		};
	}
	
	draw.mainCanvas = new draw.canvas('mainCanvas');

	draw.mainCanvas.pen.width = 5;

	var shape1, shape2, shape1_point1, shape1_point2;
	shape1 = draw.mainCanvas.shapes.add();
	shape1.points.add(5, 10, shape1.points.add(20, 100));

	draw.mainCanvas.pen.width = 15;
	draw.mainCanvas.pen.color = '#ffa500';
}

以上是关于JavaScript 2D图形库(正在进行中)的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript入门之Canvas: 2D Context

用于导航大型2D图形的简单javascript画布框架?

javascript:使用canvas绘图2D图形

第3版emWin教程第14章 emWin6.x的2D图形库之基本绘图

在 WebGL v.s. 中模拟基于调色板的图形2D画布

第3版emWin教程第19章 emWin6.x的2D图形库之绘制图形(含二维码和条形码)