随笔 - 5  文章 - 0 评论 - 51 trackbacks - 4
<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

与我联系

搜索

 

常用链接

留言簿

我参加的小组

我参与的团队

随笔档案

相册

最新评论

阅读排行榜

评论排行榜

Js绘图研究(一)
——点的实现与速度测试
Ps:本文只是一菜鸟画鸭之笔,有不对之处欢迎高手们指证!

一、背景知识:
   通过搜索,网上关于web绘图的实现大致有以下三类:
1 插件实现
     优点:功能丰富。护展性好,速度快。
     缺点:首次访问必须下载插件。
2 flash实现
     优点:首次访问不需要下载插件(大部分浏览已经安装有flash插件),画面质量高。
     缺点:速度较慢,需要懂得flash相关编程的知识。
3 js实现
     优点:首次访问不需要下载插件
     缺点:速度应该慢于插件的实现(没有测试),实现方法较牵强。
本文只介绍js实现。构思参照neweroica 于2003年发布的JS2D函数集。在小学的几何中我们就明白,绘图平面由线构成,而线是由点构成,所以,只要我们解决了点的绘制,则线,面只是一个循序渐进的过程。

二、思路解析:
 在newerroica的JS2D函数集中,点的绘制是通过table标签来实现的。也就是绘制一个无边框,无填充,一个单元格的表格,来实现点的显示。点的颜色、大小、位置则由table标签的style属性来定义。代码如下:
//Dottable.js

1/************* 画点 **************
2  x,y     点所在的屏幕坐标(像素)
3  color   颜色(字符串值)
4  size    大小(像素)
5**********************************/

6function drawDot(x,y,color,size){
7  document.write("<table border='0' cellspacing=0 cellpadding=0><tr><td style='position: absolute; left: "+(x)+"; top: "+(y)+";background-color: "+color+"' width="+size+" height="+size+"></td></tr></table>");
8}


我的改进思路是,如果table可以实现,那么div是否同样可以实现,并且能够达到更快的速度呢,我简单的修改代码如下:
//Dotdiv.js

1/**********画点***********
2x,y   点的坐标(像素)
3color 点的颜色(字符串值)
4size  点在大小(像素)
5
6**********************/

7function drawDot(x,y,color,size){
8  document.write("<div style='position: absolute; border:0;left: "+(x)+"; top: "+(y)+";background-color:"+color+"; width:"+size+"; height:"+size+"; overflow:hidden;'></div>");
9}

那么div是否真的比table快呢?我做了个简单的js测试程序段,这个程序段同样可用于更多的js脚本性能测试,代码如下:
//timer.js

 1/***********计时器****************
 2startime()       开始计时
 3endtime()        结束计时并输出时间
 4
 5*********************************/

 6var ms;
 7//开始计时
 8function starttime() {
 9 then = new Date();
10 ms= then.getTime();
11 
12}

13
14//结束计时
15function endtime() {
16        now = new Date();
17 ms=now.getTime()-ms;
18 ms=ms/1000;
19 alert("共用时:"+ms+"");
20}

三、测试
构建测试用例,我们用两种方法,分别沿45度画5百个点,分别对所用时间计数:
Ps:我的机器配置:方正t3200c笔记本电脑,p41.5的cpu,内存384M。
Table实现的测试用例代码:

 1<html>
 2<head>
 3</head>
 4<body>
 5<script src="timer.js">
 6</script>
 7<script src="dottable.js">
 8</script>
 9
10
11<script language="javascript">
12    starttime();
13    for(i=0;i<500;i++){
14        drawDot(1+i,1+i,"ff0000",1);
15    }
 
16
17    endtime();
18
</script>
19
20</body>
21</html>

运行后返回时间:0.27秒
Div实现的测试用例代码:

 1<html>
 2<head>
 3</head>
 4<body>
 5<script src="timer.js">
 6</script>
 7<script src="dotdiv.js">
 8</script>
 9
10
11<script language="javascript">
12    starttime();
13    for(i=0;i<500;i++){
14        drawDot(1+i,1+i,"ff0000",1);
15    }
 
16
17    endtime();
18
</script>
19
20</body>
21</html>

运行后返回时间:0.11秒

显然,div的运行时间明显快于table.测试成功。

未完待续

posted on 2007-12-12 14:54 acro 阅读(2794) 评论(21)  编辑 收藏 网摘

FeedBack:
#1楼  2007-12-12 21:19 abc2 [未注册用户]
没有使用意义
  回复  引用    
#2楼  2007-12-12 21:32 Hafeyang      
非常有意义
我也研究很久了
在上传图片的时候需要制作水印或者简单操作的时候,能使用js提供一个预览,自然比发送到服务器端要好,我一直想做点什么,楼主能研究这个,佩服.
对于js图片操作,最重要的是js的性能和兼容的问题.
至于博主用div和table做性能比较,结果是不言而喻的,因为浏览器在绘制整个页面的最小单位就是块状元素,table明显是一个复杂的快状元素,自然绘制的速度要比div慢
  回复  引用  查看    
#3楼  2007-12-12 21:55 Soul Huang      
关注...
  回复  引用  查看    
#4楼  2007-12-12 22:01 ayu [未注册用户]
js+cs?呵
  回复  引用    
#5楼  2007-12-12 22:15 Colin Han      
哈哈,我曾经在99年的时候尝试过类似的东西,当时,给屏幕上显示了100多个div的时候,似乎性能就已经无法忍受了。

呵呵,当时我还在用定时器在做动画,不知道是哪一个影响了性能。
  回复  引用  查看    
#7楼  2007-12-12 22:19 怪怪      
终于有人玩这个了 :).

不过绘制线和图案的时候, 不要去循环调用类似于你的DrawDot的函数, 而是直接拼出最终的字符串, 一次写到页面上. 效率还算可以用的范围内.

也就是说, 最好做一个虚拟的平面, 向这个平面内绘制, 而绘制的操作全都转化为对字符穿的增删改, 然后直接将最终的字符串搞上去. 比如, 用prototype的方式建立一个Suface类, var s = new Surface(); s.drawDot(x, y); s.drawLine(x1, y1, x2, y2); s.flush();这样的方式.

另外一个需要注意的是, 往往图形, 比如有一定宽度的斜线, 圆, 或者任意图案, 中间一些部分可以用有一定宽度和高度的DIV代替若干个DIV的组成的方阵, 这样优化下来可以节省很多DIV.

比如一个没有颜色变化的圆, 其实可以先分为一个内接正方形, 然后内接正方形上侧用高度固定越接近上部越短的div实现, 内接正方形左侧用宽度固定越左高度越小的div实现, 以此类推. 也可以做一个求div的算法, 话任意区域都使用这个算法.

这个方式效率在一般情况下不是主要问题, 主要问题是边缘部分不平滑.
  回复  引用  查看    
#8楼  2007-12-12 22:41 怪怪      
说的有点罗嗦, 就是不是简单的用一个一个的DIV点去组成线和面, 而是用不同大小的DIV方块去组成线和面, 会大幅提高效率.
  回复  引用  查看    
#9楼 [楼主] 2007-12-12 23:42 acro      
@Hafeyang
感谢关注与肯定。
呵呵,总觉得WEB绘图还有很多值得研究的东西。所以有了此文。ajax也是利用现有技术来实现的。我们虽然达不到那样的境界,但至少也会在研究中有所收获。

  回复  引用  查看    
#10楼 [楼主] 2007-12-12 23:50 acro      
@怪怪
字符串的实现类似绘图的缓存技术,而我进一步的设想是得到及时的效果,就像用铅笔写字。如果缓冲,则看步到中间效果。

你提的第二点算是矢量绘图吧?我也有想过,但是由于我想在后面进一步实现类似photoshop的笔触的效果,则更类似位图。

感谢交流,不知我的理解是否正确。
  回复  引用  查看    
#11楼  2007-12-13 00:18 cnlamar      
怪怪说的那个应该和矢量无关吧.

我觉得这样绘图,DIV的字符拼接还不是太大的问题,浏览器渲染这些DIV....会不会挂掉...
  回复  引用  查看    
#12楼  2007-12-13 00:44 Matrix      
js的绘图的话
JS + VML
或是JS + SVG这样比较正宗一些。
  回复  引用  查看    
#13楼  2007-12-13 02:31 米开朗基罗      
@Matrix
楼上的说得好,vml我刚看了下,确实很强。
不过可惜firefox现在好像不能支持啊。
  回复  引用  查看    
#14楼  2007-12-13 08:11 过去的 [未注册用户]
貌似 楼主. 是在重新发明轮子...不过研究还是可以了...记得有这样一个 JS库..wz_jsgraphics.js 国内N多地方用它..
  回复  引用    
#15楼  2007-12-13 09:16 Clark Zheng      
关注一下,不过感觉没什么前途
  回复  引用  查看    
#16楼  2007-12-13 09:22 Tony Qu      
用这个来做游戏还是有用的,不是有人做过js版星际,期待楼主的js版warcraft:)
  回复  引用  查看    
#17楼  2007-12-13 10:12 sinmen      
虽然很少用到,不过有时间研究一下,可以提高自己的能力,支持LZ
  回复  引用  查看    
#18楼  2007-12-13 10:59 Icebird      
这个思路(用div)与wz_jsgraphics是一样的
  回复  引用  查看    
很好的算法思路,顶一个

http://www.shi123.com
  回复  引用    
#20楼  2007-12-13 12:22 web报表      
收藏!!
  回复  引用  查看    
#21楼  2007-12-13 15:41 怪怪      
@acro
不是的, 只是一次操作中出现的图形如此处理. 其实在C++里也一样的, 先把操作都做到一个缓冲区内, 在反映到绘图设备上. 比如响应鼠标移动操作, 那么每次mousemove时这一个过程内, 象我说的那么处理, 速度会高很多, 有时也能减少需要的DIV数量. 当然仅仅用于实现一次绘制多点的情形, 需求就是一个点一个点绘制的, 就用不到我说的方式.

另外FF虽然没有VML, 但有SVG, IE8之后的版本可能也会支持SVG. 主要SVG作为一个标准, 得不到厂商(比如MS)的有力支持. 另外纯以画图而论, FF上还有更好用的专门画图的东西, 叫Canvas还是什么来着, 使其来超简单无比, 不过现在困糊涂了, 想不起来了....

你这种DIV的方法很显然是最通用的, 而且效率没有想象中那么差, 所以我觉得不是特别重量级的绘图的应用, 完全可以使用的.
  回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-12-12 20:26 编辑过
Google站内搜索


China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!

相关文章:

相关链接: