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

JS Canvas实现2D之点线篇
概要:HTML5 是目前正在讨论的新一代 HTML 标准,它代表了现在 Web 领域的最新的发展方向。在 HTML5 标准中,加入了新的多样的内容描述标签,直接支持表单验证,视频和音频标签,网页元素的拖拽,离线存储,工作线程等等。当然,其中一个最令人激动的新特性就是新的标签类型 Canvas,开发人员可以通过该标签,在网页上直接用脚本进行绘图,产生各种 2D 渲染的效果。所以有人预言,HTML5 将是 Flash 和 Silverlight 的“杀手”。从 Firefox 1.5 开始就已经支持 Canvas,Safari 也是很早就开始支持 Canvas。新的浏览器比如 Chrome 也是从一开始就支持。但遗憾的是,到目前为止,IE 一直不支持该标准。
HTML 5 引入了新的的网页元素:<canvas>。Canvas 是一片空白的绘图区域,网页开发者可以利用 JavaScript 在该区域中自由地进行 2D 绘图。常见的在canvas中显示自己定义格式的字体,点、线、等具体2D、3D模型,图片的效果处理等等,具体实现可见canvas相关文档。
文归正题,前段时间在我的项目中也需要js在页面中做出一些2D图像效果,我查看了很多关于canvas的文档,但是由于IE不支持统统都得放弃。关于这个功能很是可惜,但是由于我们公司项目基本基于IE实现,难道IE就不支持js 2D作图,答案显然是否定的,通过对网友一段精彩的js函数的修改,实现了我要的效果,在页面上进行2点画线,实现工程图2点测距的功能,这里我对其思路方法进行简单总结:
A.创造canvas,可以指定一页面对象为canvas,并定义其大小样式:
/**
* 用指定的id, 长和宽构造一个画板
*
* @param id html元素的id
* @param w 指定的画板宽度
* @param h 指定的画板高度
*/
var Canvas = function(id, w, h) {
// 只想Canvas实例,以修正this指针的引用错误.
var self = this;
// 缓冲器
var cache = [];
// 画板绑定到的html元素的引用
var canvas = document.getElementById(id);
// 画板底色, 默认为浅灰色
var bgColor = "lightgray";
// 笔刷的颜色, 默认为黑色
var fgColor = "black";
// 原点坐标, 初始为(0, 0)
var oX = 0, oY = 0;
// 是否允许点画到画板边界以外
var allowOutside = false;
// 渲染html元素
canvas.onselectstart = function() {return false;}
canvas.style.overflow = "hidden";
canvas.style.background = "lightblue";
canvas.style.width = (w ? w : 400) + "px";
canvas.style.height = (h ? h : 400) + "px";
        ……
}

B. 定义好canvas,然后就是作图,画布上所有的对象的基础对象就是点,所有的对象都是由点所组成的,完成了点的处理,就成功了一半:定义点,画点然后画线:
       /*
* 在给定的坐标出画点
*
* @param x x坐标
* @param y y坐标
*/
this.point = function(x, y) {
var pos = self.pos();
var size = self.size();
x = pos.x + oX + x;
y = pos.y + oY + y;

// 如果不允许在边界外显示点,则不讲该点推入缓存
if (!allowOutside
&& !((x >= pos.x && x <= pos.x + size.width)
&& (y >= pos.y && y <= pos.y + size.height)))
return;
cache.push("<span  name= 'pointxxx' style='width:1px;height:1px;position:absolute;left:" + x +"px;top:" + y + "px;background-color:" + fgColor + ";font-size:0px;z-index:999;'></span>");
}
        /**
* 数值微分法画直线
*
* @param x0 起点x坐标
* @param y0 起点y坐标
* @param x1 终点x坐标
* @param y1 终点y坐标
*/
function line_DDA(x0, y0, x1, y1) {
var px = x0, py = y0;
var dx = x1 - x0;
var dy = y1 - y0;
var incX = 0, incY = 0;
var epsl = Math.abs(dx) > Math.abs(dy) ? Math.abs(dx) : Math.abs(dy);
incX = dx / epsl;
incY = dy / epsl;
for (var i = 0; i < epsl; i++) {
self.point(parseInt(px + 0.5), parseInt(py + 0.5));
px += incX;
py += incY;
}
}
/**
* 用给定的起点和终点坐标画直线
*
* @param x0 起点x坐标
* @param y0 起点y坐标
* @param x1 终点x坐标
* @param y1 终点y坐标
*/
this.line = function(x0, y0, x1, y1) {
line_DDA(x0, y0, x1, y1);
}
/**
         * 清空画板
*/
this.clear = function() {
cache = [];
canvas.innerHTML = "";
}
/**
* 清空直线
*/
this.clearPoint = function() {
//alert(canvas.innerHTML)
var p2 = getElementsByName1("span","pointxxx");
 
//alert(p2.length)
for(var i=0;i<p2.length;i++)
canvas.removeChild(p2[i]);
}
其实点画好了,是他的平面对象都是根据数学模型及循环知识由点拼出,