FreeOZ论坛

标题: javascript库求推荐 [打印本页]

作者: woodheadz    时间: 16-1-2012 20:31
标题: javascript库求推荐
MS对.net/C#平台的态度十分不明朗,公司开始考虑全面迁移到javascript/html5平台的可能性。
这两天在寻找合适的开源js库,请大家推荐。
基本的要求是:
1.基于canvas
2.提供带zorder的hittest支持
3.提供基于canvas的绘图扩展
4.一定的动画支持
5.最好提供一定的重绘区域管理功能。因为需要支持较高的分辨率,很多游戏js库的那种每帧全部自动刷新的方式估计会有效率问题。
6.如果自带部分控件库就更好了。
作者: woodheadz    时间: 16-1-2012 20:36
对了,还有一条,就是license允许用于商业用途
作者: coredump    时间: 16-1-2012 20:38
sencha
作者: coredump    时间: 16-1-2012 20:43
标题: 回复 #1 woodheadz 的帖子
我很喜欢HTML5, 2011年几乎全年都在折腾canvas标准的实现
作者: woodheadz    时间: 16-1-2012 20:44
对了,再加一条,最好提供touch支持!
作者: woodheadz    时间: 16-1-2012 20:46
原帖由 coredump 于 16-1-2012 21:43 发表
我很喜欢HTML5, 2011年几乎全年都在折腾canvas标准的实现

你在搞实现啊? 有点厉害哦
我才开始应用
作者: woodheadz    时间: 16-1-2012 20:48
原帖由 coredump 于 16-1-2012 21:43 发表
我很喜欢HTML5, 2011年几乎全年都在折腾canvas标准的实现

我主要是不大喜欢javascript,其实所有弱类型的语言我都不大喜欢。
但对html5的绘图效率还真是觉得惊喜
作者: 狮子的眼睛    时间: 16-1-2012 21:30
跟随微软好像不大好。

1 倾向于把开发人员变成傻瓜,鼠标一点帮你搞定一切。
2 自己技术路线不清晰,抄袭其他人的技术,抛弃自己的。
作者: huazhb    时间: 16-1-2012 21:31
为什么说MS对.net/C#平台的态度十分不明朗呢?我觉得MS的态度很清楚啊。 跨平台的HTML5, 微软平台的尽可以用C#啊
作者: 周星星1832    时间: 16-1-2012 21:33
jquery
作者: trisun    时间: 16-1-2012 21:48
用Vaadin + GWT 纯 Java ,比直接用Javascripts 好多了,可以很容易支持第三方Javascripts 库 (JSNI),比直接用Javacripts 开发效率高。
作者: 周星星1832    时间: 16-1-2012 21:55
smarty GWT.
不喜欢
作者: coredump    时间: 16-1-2012 22:00
原帖由 woodheadz 于 16-1-2012 20:48 发表

我主要是不大喜欢javascript,其实所有弱类型的语言我都不大喜欢。
但对html5的绘图效率还真是觉得惊喜
别太高兴, canvas绘图再利用硬件加速上还有很长的路要走, 所以大部分还是软件渲染, OpenGL和canvas的2d api有很多不可调和的矛盾.

如果是做game, 可以考虑直接上webgl
作者: coredump    时间: 16-1-2012 22:01
原帖由 huazhb 于 16-1-2012 21:31 发表
为什么说MS对.net/C#平台的态度十分不明朗呢?我觉得MS的态度很清楚啊。 跨平台的HTML5, 微软平台的尽可以用C#啊

Win8开始把HTML5和Javascript作为first class支持了.
作者: coredump    时间: 16-1-2012 22:02
原帖由 trisun 于 16-1-2012 21:48 发表
用Vaadin + GWT 纯 Java ,比直接用Javascripts 好多了,可以很容易支持第三方Javascripts 库 (JSNI),比直接用Javacripts 开发效率高。

我说不上真正的理由, 不过潜意识里就不喜欢GWT这样的思路, 不过GWT优点的确很多.
作者: woodheadz    时间: 16-1-2012 23:10
原帖由 coredump 于 16-1-2012 23:00 发表
别太高兴, canvas绘图再利用硬件加速上还有很长的路要走, 所以大部分还是软件渲染, OpenGL和canvas的2d api有很多不可调和的矛盾.

如果是做game, 可以考虑直接上webgl

不是game,是正经八百的应用软件。
但我们的软件有大量的绘图和动画,所以基本上只能考虑html5. 我前两天直接用canvas做了几个效率测试(win平台,chrome和ie9),感觉效率实在很棒。
但因为这个平台太新,很担心会碰到大的技术风险。
作者: woodheadz    时间: 16-1-2012 23:12
原帖由 trisun 于 16-1-2012 22:48 发表
用Vaadin + GWT 纯 Java ,比直接用Javascripts 好多了,可以很容易支持第三方Javascripts 库 (JSNI),比直接用Javacripts 开发效率高。

我们的应用比较特殊,开发效率我们这儿可以基本不用考虑。 用java的话,可能在苹果、win8的app store方面碰到问题。
作者: coredump    时间: 16-1-2012 23:16
原帖由 woodheadz 于 16-1-2012 23:10 发表

不是game,是正经八百的应用软件。
但我们的软件有大量的绘图和动画,所以基本上只能考虑html5. 我前两天直接用canvas做了几个效率测试(win平台,chrome和ie9),感觉效率实在很棒。
但因为这个平台太新,很担心 ...

基本的2d绘图应用, canvas完全可以胜任, vmware都用canvas做远程桌面客户端了.
作者: woodheadz    时间: 16-1-2012 23:20
原帖由 huazhb 于 16-1-2012 22:31 发表
为什么说MS对.net/C#平台的态度十分不明朗呢?我觉得MS的态度很清楚啊。 跨平台的HTML5, 微软平台的尽可以用C#啊

win8 里能上metro UI的app应用必须使用winrt,而不是.net, 而winrt甚至连个dc都取不到。 如果有复杂的自定义图形,要么使用Javascript,要么使用directx,根本无法用C#。
我觉得MS现在已经被苹果和google搞得阵脚大乱,自己家的看家本事都要弄丢了
作者: woodheadz    时间: 16-1-2012 23:26
原帖由 coredump 于 17-1-2012 00:16 发表

基本的2d绘图应用, canvas完全可以胜任, vmware都用canvas做远程桌面客户端了.

嘿嘿,你这句话让我安心不少啊
对了,你在做的html实现是用在哪个浏览器上的?
作者: coredump    时间: 16-1-2012 23:32
原帖由 woodheadz 于 16-1-2012 23:26 发表

嘿嘿,你这句话让我安心不少啊
对了,你在做的html实现是用在哪个浏览器上的?

Qt的qml框架里的, 不是浏览器的.
作者: woodheadz    时间: 19-1-2012 11:50
今天研究开源库Kinetic,主要想搞清楚它的hittest是怎么实现的,结果真是很让人吃惊。
Kinetic有个Shape对象,系统自动完成Shape对象的绘制准备工作(Scale,Rotate...)后调用回调传出context让调用端完成Shape的绘制。调用端绘制的图形自动支持hitTest检查。
实现的方式居然是每次做hitTest检查时:
1.以zindex逆序遍历所有的Shape对象,让Shape对象将图形逐个绘制到一个不可见的canvas上(这个canvas大小位置和可见canvas完全一样)
2.每绘制完一个图形,在不可见canvas上执行isPointInPath,如果为真则认为hit到,否则继续。

不可思议的是这样做似乎效率还不错!

有一个简单的替代方案是为每个对象单独创建一个canvas,这样程序就会非常简单,并且也能够自然支持复合模式(kinetic目前最大的问题就是不支持Shape复合)。Kinetic不采用这种模式,难道canvas那么消耗资源?
作者: mason00    时间: 19-1-2012 12:23
微软不是官方主推支持jquery吗?不过对于HTML5的特性是IE9跟不太上,所以微软也就没办法表明官方推荐什么库。反正我还是停留在HTML5之前的javascript库的,似乎是手机客户端对HTML5的特性比较需要,火了sencha哈。.Net应该可以直接掉winrt的API,不过所有HTML5的特性都是需要浏览器去支持的吧,也就是IE里面实现的javascript支持多少HTML5对象和方法咯
作者: woodheadz    时间: 19-1-2012 12:55
原帖由 mason00 于 19-1-2012 13:23 发表
微软不是官方主推支持jquery吗?不过对于HTML5的特性是IE9跟不太上,所以微软也就没办法表明官方推荐什么库。反正我还是停留在HTML5之前的javascript库的,似乎是手机客户端对HTML5的特性比较需要,火了sencha哈。.N ...

我们的需求比较特别,重点在于绘图功能和图形功能的互动方面,而不是组件库上。所以得找找jquery,sencha之类的UI框架以外的东西
作者: coredump    时间: 19-1-2012 13:43
原帖由 woodheadz 于 19-1-2012 11:50 发表
今天研究开源库Kinetic,主要想搞清楚它的hittest是怎么实现的,结果真是很让人吃惊。
Kinetic有个Shape对象,系统自动完成Shape对象的绘制准备工作(Scale,Rotate...)后调用回调传出context让调用端完成Shape的绘 ...
因为Canvas是立即模式的绘图, 其实就是像素操作, 所有在没有DOM可以依赖的前提下那么最终hittest都会落在isPointInPath上。


你说的多个Canvas也是常用的模式之一。
作者: coredump    时间: 19-1-2012 13:46
原帖由 woodheadz 于 19-1-2012 12:55 发表

我们的需求比较特别,重点在于绘图功能和图形功能的互动方面,而不是组件库上。所以得找找jquery,sencha之类的UI框架以外的东西

如果不需要太多的UI组件框架,而只是焦点在Canvas绘图上,也可以研究下 Fabric
https://github.com/kangax/fabric.js/
后台建立在Node.js上, 目标之一就是速度。
Demo:http://kangax.github.com/fabric.js/kitchensink/
MIT license, 应该也符合你的要求

[ 本帖最后由 coredump 于 19-1-2012 13:50 编辑 ]
作者: coredump    时间: 19-1-2012 13:54
在性能上Fabric就是用的多Canvas方式, 不过不是每个对象一个Canvas这么极端,因为这样反而完全丧失了Canvas做为2D底层绘图的优势,Fabric使用的是2层 Canvas。

https://github.com/kangax/fabric.js/wiki/Focus-on-speed
作者: coredump    时间: 19-1-2012 13:54
这里有一个Fabric的PPT
http://www.slideshare.net/kangax ... ng-acanvaslibrarybk
作者: woodheadz    时间: 19-1-2012 14:46
原帖由 coredump 于 19-1-2012 14:54 发表
在性能上Fabric就是用的多Canvas方式, 不过不是每个对象一个Canvas这么极端,因为这样反而完全丧失了Canvas做为2D底层绘图的优势,Fabric使用的是2层 Canvas。

https://github.com/kangax/fabric.js/wiki/Focus- ...

Kinetic也用了很多个canvas(7个)。和Fabric类似,它也是每个canvas有不同的作用,比如有绘制静态背景的canvas,不需要hittest支持的对象的canvas等等。每一层canvas上可以同时绘制多个对象。为了分清楚用户点击鼠标时到底是点中了canvas上的哪个对象,它就采取了那么一种我觉得有点“极端”的hitTest测试方式。
如果每个对象单独放一个canvas,那么只需要针对不同的canvas执行isPointInPath即可,而不用像Kinetic一样,把所有需要hitTest测试的对象全部重绘一次(最坏的情况下)才能得到结果。
正在研究另一个游戏js库EaselJS,号称要用JS模拟Flash对象模型的,看到现在觉得他们似乎是用每个对象一个canvas的方式。 但EaselJS的动画效率似乎没有Kinetic的效率来得好。

Fabric还没仔细研究,看它的介绍似乎偏重于SVG之类的复杂图形的支持? 我们的绘图不会那么复杂,但会有很多需要执行hitTest的对象,不知道适用不?
等研究完EaselJS再去看看
作者: coredump    时间: 19-1-2012 15:34
原帖由 woodheadz 于 19-1-2012 14:46 发表
把所有需要hitTest测试的对象全部重绘一次(最坏的情况下)才能得到结果。...

我觉得这个之所以没想像中性能那么差, 是因为hitTest本来就是个慢速,低频率的事情, 现在的机器, 一个满屏的canvas, 重绘的FPS也很快, 如果跑到移动设备上, 硬件是差了, 可是屏幕也小了, 所以,都在可接受的范围内, hitTest成不了瓶颈点。
作者: woodheadz    时间: 19-1-2012 16:05
原帖由 coredump 于 19-1-2012 16:34 发表

我觉得这个之所以没想像中性能那么差, 是因为hitTest本来就是个慢速,低频率的事情, 现在的机器, 一个满屏的canvas, 重绘的FPS也很快, 如果跑到移动设备上, 硬件是差了, 可是屏幕也小了, 所以,都在可接受 ...

鼠标移动的时候每秒钟还是能有好多个MouseOver事件需要进行HitTest检查,当然对于touch设备比较好办,因为不会随时有那么多MouseOver事件会触发hitTest检查,即便效率低点也无所谓。
我做了个测试,在1900*1000分辨率的canvas上做10000个对象的检查,就会有点慢。我想如果在它做hitTest前再加上绘图对象的矩形边界检查来过滤一下,性能应该能大幅度提高到能够接受的地步了。

现在我的担心就是要在Kinetic现在的基础上加入复合的UI对象支持工作量会有点大,从事件机制到重绘、hitTest机制都需要修改。 我还是先看看其它的框架再决定。
作者: coredump    时间: 20-1-2012 17:45
标题: 回复 #31 woodheadz 的帖子
在Canvas中检测鼠标事件有很多种有意思的方法, StackOverFlow上这个帖子很有参考价值

http://stackoverflow.com/questio ... thin-an-html-canvas
作者: woodheadz    时间: 20-1-2012 18:10
原帖由 coredump 于 20-1-2012 18:45 发表
在Canvas中检测鼠标事件有很多种有意思的方法, StackOverFlow上这个帖子很有参考价值

http://stackoverflow.com/questio ... thin-an-html-canvas

果然很多人都碰到这个问题。到目前为止,看来那种重绘到隐藏canvas上的方法算是比较不错的方法了
作者: woodheadz    时间: 24-1-2012 16:51
考察了几个JS库,比较起来还是Kinetic和Easel JS最符合我们的需求,但都有各自的问题。
现在决定自己写一个,反正Kinetic和Easel JS都是MIT的授权协议,很多地方大可好好借鉴下他们的方式。

作者: coredump    时间: 24-1-2012 16:54
原帖由 woodheadz 于 24-1-2012 16:51 发表
考察了几个JS库,比较起来还是Kinetic和Easel JS最符合我们的需求,但都有各自的问题。
现在决定自己写一个,反正Kinetic和Easel JS都是MIT的授权协议,很多地方大可好好借鉴下他们的方式。

别忘了open source
作者: woodheadz    时间: 24-1-2012 19:15
原帖由 coredump 于 24-1-2012 17:54 发表

别忘了open source

我倒是想开源,但最后能不能开就看老板的了
作者: 蒙面超人    时间: 24-1-2012 20:58
标题: 回复 #4 coredump 的帖子
欢迎老丐开讲座介绍HTML5应用!
作者: woodheadz    时间: 24-1-2012 21:09
搞了这几天,对canvas的强大简直十分满意
IE9现在对canvas的优化支持简直没得说,速度超快不说,还自带2D图形的抗锯齿。相比起来,Chrome绘图效率就明显不如,而且一旦对2d图形进行旋转缩放,最终的效果比ie就差太多了。
MS毕竟积淀深厚,又是自家平台,一旦真的用心搞搞,别人实在是搞不过他的。
作者: woodheadz    时间: 24-1-2012 21:15
发现FireFox也有2d抗锯齿,chrome的效果还真是惨不忍睹啊....
作者: coredump    时间: 24-1-2012 21:49
原帖由 woodheadz 于 24-1-2012 21:09 发表
搞了这几天,对canvas的强大简直十分满意
IE9现在对canvas的优化支持简直没得说,速度超快不说,还自带2D图形的抗锯齿。相比起来,Chrome绘图效率就明显不如,而且一旦对2d图形进行旋转缩放,最终的效果比ie就差太多 ...

Chrome底层用的是Skia 2D图形库, IE9用的是DirectWrite, 两者都有抗锯齿。

不过IE9默认开启Canvas的硬件加速了,Chrome现在版本要手工启用:
about:flags
打开
GPU Accelerated Compositing
GPU Accelerated Canvas 2D
作者: coredump    时间: 24-1-2012 21:51
原帖由 woodheadz 于 24-1-2012 21:15 发表
发现FireFox也有2d抗锯齿,chrome的效果还真是惨不忍睹啊....

使用GPU的话,抗锯齿是很轻松的一件事情, 俺们写的canvas也抗锯齿, 其实就是用的OpenGL多重采样设置一下就行了
作者: woodheadz    时间: 24-1-2012 22:04
原帖由 coredump 于 24-1-2012 22:51 发表

使用GPU的话,抗锯齿是很轻松的一件事情, 俺们写的canvas也抗锯齿, 其实就是用的OpenGL多重采样设置一下就行了

开启以后好几个网页都成了大花脸
是不是我用的chrome版本是beta的缘故? 17的beta版
效率问题还好办,总可以通过优化程序解决。但抗锯齿问题就很头痛了... 没有抗锯齿,很多2D图形效果是在是很悲惨...

[ 本帖最后由 woodheadz 于 24-1-2012 23:22 编辑 ]
作者: woodheadz    时间: 24-1-2012 22:16
原帖由 coredump 于 24-1-2012 22:51 发表

使用GPU的话,抗锯齿是很轻松的一件事情, 俺们写的canvas也抗锯齿, 其实就是用的OpenGL多重采样设置一下就行了

对了,还有个问题请教:
我这段时间看的js库基本上都采用每帧全canvas暴力刷新的方式完成动画。在高分辨率下,ie似乎还撑得住,但chrome就有点不行了。
如果修改为每帧刷新前先计算出无效区域,然后清除这个区域,设置clip region后再重绘,效率应该会明显有改善吧?
我打算在自己的实现的框架里用这种方式,但因此必然会增加不少工作量。所以做之前先打听打听
搞不懂为什么没人这么做,难道效率不会有区别?

[ 本帖最后由 woodheadz 于 24-1-2012 23:17 编辑 ]
作者: coredump    时间: 24-1-2012 22:41
原帖由 woodheadz 于 24-1-2012 22:16 发表

对了,还有个问题请教:
我这段时间看的js库基本上都采用每帧全canvas暴力刷新的方式完成动画。在高分辨率下,ie似乎还撑得住,但chrome就有点不行了。
如果修改为每帧刷新前先计算出无效区域,然后清除这个区域 ...

我写的canvas实现因为不需要严格遵守canvas的规范, 就从实现上用了这个方式, 术语上称作tiled rendering(分片渲染).
有些canvas framework也用了这个概念(比如这个, 还有这个), 特别是在地图和游戏类型的应用中, tiled rendering是很基本的概念.
作者: coredump    时间: 24-1-2012 22:51
我的chrome好像没有反锯齿的问题

chrome 18.0.1010.0 on Mac OS 10.7
作者: woodheadz    时间: 24-1-2012 22:59
原帖由 coredump 于 24-1-2012 23:41 发表

我写的canvas实现因为不需要严格遵守canvas的规范, 就从实现上用了这个方式, 术语上称作tiled rendering(分片渲染).
有些canvas framework也用了这个概念(比如这个, 还有这个), 特别是在地图和游戏类型的应用中,  ...

似乎这个和我想的略有不同。
我尝试说说我对这个tiled rendering的理解你看对不:
tiled rendering应该是当所绘制的区域非常庞大时,首先将整个区域分小块存储,然后根据当前的“视区”范围从区域中选出可见的小块绘制。这样可以极大的提高绘制速度。

而我要解决的问题是当“视区”很大(高分辨率)时,为了提高效率,重绘时首先找出整个视区中需要重绘的部分(通常很小),仅仅清除这些部分,然后把这些区域设置为clip region,再调用和这些部分相交的图形对象的绘制代码完成绘制。因为重绘的区域比较小,所以效率会比较高(这点我猜的,以前做GDI编程的时候是这样,不知道对canvas而言是不是这样?)
这段时间我看的JS库基本上是清除整个canvas区域,然后全部重绘。
作者: coredump    时间: 24-1-2012 23:08
标题: 回复 #46 woodheadz 的帖子
这里有3个概念
1. tile size   每次绘制的小方块的大小
2. canvas size  整个画布的逻辑上的大小
3. canvas window size  canvas这个元素的大小

如果2 > 3 而且 2> 1的时候, 就是你说的第一种的情况, 这个时候1和3谁大谁小无所谓, 根据需要定

如果3 = 2的时候, 把3(2)分成很多个小的1, 那么就是你说的第二种情况

从算法上来说, 这两种情况没有区别
作者: woodheadz    时间: 24-1-2012 23:15
原帖由 coredump 于 24-1-2012 23:51 发表
我的chrome好像没有反锯齿的问题

chrome 18.0.1010.0 on Mac OS 10.7


我用这段代码:
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.fillStyle = "#FF0000";
context.fillRect(10, 10, 100, 50);
context.rotate(-Math.PI / 20);
context.fillStyle = "blue";
context.fillRect(10, 80, 100, 50);

从左到右分别是Firefox 9,IE9和Chrome17(没开硬件加速):
[attach]217970[/attach]

用浏览器自带的放大功能放大后更是惨不忍睹:
[attach]217971[/attach]
作者: woodheadz    时间: 24-1-2012 23:27
原帖由 coredump 于 25-1-2012 00:08 发表
这里有3个概念
1. tile size   每次绘制的小方块的大小
2. canvas size  整个画布的逻辑上的大小
3. canvas window size  canvas这个元素的大小

如果2 > 3 而且 2> 1的时候, 就是你说的第一种的情况, 这个时候 ...

在算法模型上看,基本没区别。但在实践上区别就很大。
比如这个tile engine,在绝大多数时候canvas,也就是视区是需要整个重绘的,所以我相信他不会去理会部分的重绘的问题。
但在有些图形场景(比如我们的应用)中,多数时候发生变化的区域只占整个canvas可视面积的一小部分,如果减小重绘面积能够提高效率,那么花这个功夫去处理好部分重绘就是值得的。
作者: coredump    时间: 24-1-2012 23:33
标题: 回复 #49 woodheadz 的帖子
这个只需要根据需要做简单判断就行了, 也就是决定具体的绘制区域上.

context2d 有clip方法, 所以即使具体的绘制没有严格遵守重绘区域的约定也可以剪裁掉, 而大部分底层clip实现可以保证足够的高效, 也就是说被裁减掉的部分, 基本上不影响效率.
作者: black_zerg    时间: 24-1-2012 23:38
提示: 作者被禁止或删除, 无法发言 强,我最近也在用gwt和canvas搞自己的一个小项目
作者: black_zerg    时间: 24-1-2012 23:45
提示: 作者被禁止或删除, 无法发言 标题: 不知道是不是这个意思
我当时找过检测点在polygon里,最后发现有个 W. Randolph Franklin 的代码 我给整理成了java的:

public static boolean pnpoly(int nvert, double[] vertx, double[] verty,
                        double testx, double testy) {
                int i, j = 0;
                boolean c = false;
                for (i = 0, j = nvert - 1; i < nvert; j = i++) {
                        if (((verty > testy) != (verty[j] > testy))
                                        && (testx < (vertx[j] - vertx) * (testy - verty)
                                                        / (verty[j] - verty) + vertx))
                                c = !c;
                }
                return c;
        }

我其实不确定我明白你的意思,不过我当时每个图形都会保存一个方形的信封,检查的时候先查信封,如果不在信封里就直接排除了,否则就用上面那个方法检查点是否在polygon里面。因为我的模型都是几何模型,也就是说canvas只是绘图的实现而已。如果polygon不复杂,这种计算应该是很快的。

按照我对canvas的理解,canvas最好依赖在后台的一个结构上做成mvc那种模型,因为本身canvas和vml svg什么的差很多,canvas画完了就完了,他也没有一个图形一个对象那种概念。

[ 本帖最后由 black_zerg 于 25-1-2012 00:58 编辑 ]
作者: coredump    时间: 24-1-2012 23:46
原帖由 woodheadz 于 24-1-2012 23:15 发表


我用这段代码:
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.fillStyle = "#FF0000";
context.fillRect(10, 10, 100, 50);
context.rotate(-Math. ...
好像的确如此啊, 应该是chrome canvas实现的一个bug, 因为它的skia引擎肯定是支持反锯齿的
作者: coredump    时间: 24-1-2012 23:54
原帖由 black_zerg 于 24-1-2012 23:45 发表
我当时找过检测点在polygon里,最后发现有个 W. Randolph Franklin 的代码 我给整理成了java的:

public static boolean pnpoly(int nvert, double[] vertx, double[] verty,
                        double testx, double testy) {
...

PIP有2种经典算法,  一种叫奇偶算法, 一种叫Winding number算法, 维基上有2个很好的图来说明这两个算法

                               
登录/注册后可看大图


                               
登录/注册后可看大图


这个其实受影响最大的是填充时的效果, 不同的算法导致的填充不一样, canvas的fill()方法要求的算法实现是后一种.
作者: black_zerg    时间: 25-1-2012 00:00
提示: 作者被禁止或删除, 无法发言 果然研究的深刻!我的polygon全部给强制成simple polygon了,所以也不用管那么多 ^_^。
作者: coredump    时间: 25-1-2012 00:06
原帖由 black_zerg 于 24-1-2012 23:45 发表
按照我对canvas的理解,canvas最好依赖在后台的一个结构上做成mvc那种模型,因为本身canvas和vml svg什么的差很多,canvas画完了就完了,他也没有一个图形一个对象那种概念。

是滴, canvas和svg正好代表了2d绘图的两种风格
canvas是立即模式的代表, svg是保留模式的代表

直觉上来说, 我们总会觉得保留模式应该更受青睐一点, 可惜事实上相反, canvas这种立即模式成了香饽饽, svg却被打入冷宫.

其实不是保留模式不好(现在大家都在canvas里实现svg早已实现了很久的东西, 就是证明), 而是svg被龟速的DOM给陷害了, 而且出道太早, 那时候所有的DOM实现都比较差, 所以svg是命不好占主要原因.
作者: woodheadz    时间: 25-1-2012 00:07
原帖由 black_zerg 于 25-1-2012 00:45 发表
我当时找过检测点在polygon里,最后发现有个 W. Randolph Franklin 的代码 我给整理成了java的:

public static boolean pnpoly(int nvert, double[] vertx, double[] verty,
                        double testx, double testy) {
...

谢谢分享,只是现在我面临的状况无法使用这种方式。因为第一我们有背景透明的点阵图,第二有非闭合的线条的hittest
作者: woodheadz    时间: 25-1-2012 00:09
原帖由 coredump 于 25-1-2012 01:06 发表

是滴, canvas和svg正好代表了2d绘图的两种风格
canvas是立即模式的代表, svg是保留模式的代表

直觉上来说, 我们总会觉得保留模式应该更受青睐一点, 可惜事实上相反, canvas这种立即模式成了香饽饽, svg却被打入 ...

wpf应该是做得很不错的保留模式的实例了  只可惜命不好
作者: coredump    时间: 25-1-2012 00:11
原帖由 woodheadz 于 25-1-2012 00:09 发表

wpf应该是做得很不错的保留模式的实例了  只可惜命不好

我们的Qt QML也是保留模式的经典, JavaFX也算一个了.
作者: black_zerg    时间: 25-1-2012 00:21
提示: 作者被禁止或删除, 无法发言
原帖由 woodheadz 于 24-1-2012 17:51 发表
考察了几个JS库,比较起来还是Kinetic和Easel JS最符合我们的需求,但都有各自的问题。
现在决定自己写一个,反正Kinetic和Easel JS都是MIT的授权协议,很多地方大可好好借鉴下他们的方式。


强啊,我发现我是只能用jquery写短的javascript,写大段的马上就脑残。
作者: woodheadz    时间: 25-1-2012 00:39
原帖由 coredump 于 25-1-2012 00:33 发表
这个只需要根据需要做简单判断就行了, 也就是决定具体的绘制区域上.

context2d 有clip方法, 所以即使具体的绘制没有严格遵守重绘区域的约定也可以剪裁掉, 而大部分底层clip实现可以保证足够的高效, 也就是说被裁减 ...

可能我之前没表达清楚:
canvas重绘的方式是先清除,然后重新绘制新的图像。我的意思是清除时只清除发生变化的部分,然后只掉用和发生变化部分相关的绘图代码绘制新图。此时如果有某一部分代码绘制的图像只有一部分被包含在被清除的区域,而这个图像中又包含了半透明的像素的话,这些在区域外的点在重绘后就是错的。加入clip区域后就能防止这种情况的出现。
clip区域处理多余图像的效率我到是不担心,我担心的是这种尽量减小重绘区域面积的方式能多大程度上提高绘图效率?
因为我还需要处理我的framework里图像对象之间的亲子复合关系,还计划支持图形对象的旋转缩放,所以要想得出这个清除区域的话就涉及到大量的坐标映射计算,工作量不小。所以我想先确认下这个问题

[ 本帖最后由 woodheadz 于 25-1-2012 01:45 编辑 ]
作者: woodheadz    时间: 25-1-2012 00:44
原帖由 coredump 于 25-1-2012 01:11 发表

我们的Qt QML也是保留模式的经典, JavaFX也算一个了.

参与一个伟大产品的制作过程,感觉很爽吧?
作者: coredump    时间: 25-1-2012 00:45
标题: 回复 #61 woodheadz 的帖子
没觉得你这个有什么特别的啊, 也不需要特别多的计算量.  效率提高是肯定的, 不过我建议还是估计下你是否真的需要, 因为很可能不是很需要.

优化的事情, 等不得不优化的时候再说, 因为这个基本上不会影响上层的逻辑.
作者: coredump    时间: 25-1-2012 00:46
原帖由 woodheadz 于 25-1-2012 00:44 发表

参与一个伟大产品的制作过程,感觉很爽吧?

什么感觉都有, 有时候觉得别人都很聪明, 自己很白痴.

而且做实现的, 很多时候其实不如做上层应用带来的感觉爽.
作者: woodheadz    时间: 25-1-2012 01:00
原帖由 coredump 于 25-1-2012 01:45 发表
没觉得你这个有什么特别的啊, 也不需要特别多的计算量.  效率提高是肯定的, 不过我建议还是估计下你是否真的需要, 因为很可能不是很需要.

优化的事情, 等不得不优化的时候再说, 因为这个基本上不会影响上层的逻辑 ...

我这两天用全canvas重绘的方式做了个demo,在chrome中高分辨率下明显感觉到动画不顺。正式的产品动画还会复杂很多,所以我很担心,这涉及到可行性的问题。
我打算用的这个方式在gdi年代很常见,但这段时间看的js库没一个这么干的,所以才会产生疑惑。
这样做计算量的确不会大,但这些算法对于我这个不大会用矩阵做坐标变换的程序猿而言,想起来还是有点头大
作者: coredump    时间: 25-1-2012 01:07
标题: 回复 #65 woodheadz 的帖子
现在js库中这样做的少, 主要还是大部分都还没遇到性能问题, 但是一些正式的应用, 比如google maps, 它的很多理念都是这样的, 有时候还只能这样,别无他法.

程序猿旁边要是有个程序媛往往对缓解头大有帮助
作者: woodheadz    时间: 25-1-2012 09:19
原帖由 coredump 于 25-1-2012 02:07 发表
现在js库中这样做的少, 主要还是大部分都还没遇到性能问题, 但是一些正式的应用, 比如google maps, 它的很多理念都是这样的, 有时候还只能这样,别无他法.

程序猿旁边要是有个程序媛往往对缓解头大有帮助

嘿嘿,刚在EsealJS库里找到个Matrix对象,看起来挺好用的,一定程度上缓解了没有程序媛在身边的时候头大的问题
作者: woodheadz    时间: 25-1-2012 12:19
EasealJS库的Matrix有bug,kill了我一早上的时间     
看来核心技术还得自己掌握
作者: woodheadz    时间: 30-1-2012 00:23
初步完工了一个简单的UI框架,把前面基于Kinetic做的demo移植后重新跑起来了。
新的框架的实现方式是这样的:
1.支持复合关系,即UI对象之间的父子关系。子对象除了相对于父对象的X,Y坐标外还可以设置缩放、旋转。这部分使用了一个矩阵来进行坐标变换(JS想找个好用的矩阵类怎么就那么难 ),这个矩阵在调用子对象的重绘方法前会被框架应用到context上, 所以子对象绘制自己时可以使用本地坐标。另外子对象的鼠标/触摸相关事件中也会由框架传子对象的本地坐标(支持旋转和缩放变换),方便编程。

2.提供了ClipToBounds属性,设置后可以确保子对象在父对象边界外的内容不被显示,也不被hittest感知。这部分用canvas的clip很好实现,hittest的时候检查下这个属性即可。

3.Hittest学习了Kinetic的做法,但在做test之前先使用bounds过滤一下,大幅提高效率。

4.重绘方面现在暂时使用全屏重绘的方式,回头计划修改为部分重绘,到时候再附上效率测试报告

5.做了个十分简单但很好用的动画类,JS干这种活真是不赖。现在还少了一些ease函数,回头上网找找算法。

新框架在使用上比Kinetic和easelJS要复杂些(因为要提供对象的长宽),但效率上我相信会强一点。如果将来老板同意开源,我考虑使用这种方式自动帮助用户计算长宽:覆盖context的所有绘图方法,在绘图前先根据绘图内容自动修改长和宽。 这样感觉就很强悍了。这点现在对我们将要开发的产品没啥意义,因为所有绘制的东西的尺寸数据模型上都有详细的记录。
   
另外关于卷屏和全屏缩放,虽然用canvas实现会很简单,但因为涉及全屏刷新,效率太低。我在想能不能用css从canvas外部来实现? 这样我就只需要重绘新显示出来的部分即可,避开全屏刷新。

总的感觉,虽然我还是很不喜欢Javascript,但不得不承认js的开发效率实在不错
作者: woodheadz    时间: 2-2-2012 17:17
编了个程序测试浏览器的浮点运算性能,结果太让人吃惊了。
chrome居然1秒多就完成任务,firefox 6秒多而IE9居然要花190多秒
同样的计算C#也要6秒多。
chrome快得太变态,而IE慢得也太变态了

IE看来就是绘图性能牛逼,js执行性能差的不是一点半点
作者: black_zerg    时间: 2-2-2012 18:04
提示: 作者被禁止或删除, 无法发言 javascript 动画需要考虑性能,因为javascript是单线程。我本来的动画效果蛮好,到一个烂机器上一看悲剧得不行
作者: woodheadz    时间: 6-2-2012 16:10
原帖由 black_zerg 于 2-2-2012 19:04 发表
javascript 动画需要考虑性能,因为javascript是单线程。我本来的动画效果蛮好,到一个烂机器上一看悲剧得不行

现在我也就是在和性能做搏斗...
我的引擎现在效率已经能达到将近Kinetic的一倍, 我的显示器(2560×1600)上,IE9全屏动画基本上接近可以接受的效率。但在chrome上还是不行。另外在IPad上以IPad的分辨率来也不够,很头疼啊....

还有就是使用canvas绘制出来的文本边缘发虚(估计是抗锯齿的缘故),一旦字体小了识别方面可能就有问题。
现在我在考虑使用svg绘制文本,另外打印的时候直接把整个图绘制成svg打印。
这样就需要对canvas的context做一个抽象。之前好像见过类似的开源项目,应该不会很复杂吧...
作者: woodheadz    时间: 7-2-2012 17:30
SVG的绘制速度一般而言肯定慢于canvas,但我忽然想到如果做动画,尤其是高分辨率下以移动对象为主的全屏动画我觉得就不一定了。因为SVG的重绘策略由浏览器决定,在移动对象的动画中浏览器是有可能通过缓存、显卡buffer操作等策略极大提升效率的。

因为要用到SVG,所以顺便对SVG和canvas来了个对比测试,测试方式是画1000个各色矩形,在矩形上绘制文本, 然后用动画随机移动。

结果相当有趣。

— | canvas | svg
ie9 | 15 | 11
chrome | 7.5 | 9

这是在FullHD的分辨率下测得的数据。

也就是说在这个测试中IE的canvas来得比svg快而在chrome中则反了过来。
文本渲染的质量svg明显强过canvas,编程方面svg也有明显的优势。

真难以取舍啊....
作者: coredump    时间: 7-2-2012 18:10
标题: 回复 #73 woodheadz 的帖子
canvas的文本部分就是个灾难, 能不用完全不要用,切记!
http://simonsarris.com/blog/322- ... -considered-harmful

实际上可以直接用canvas结合div和其他html元素, 不一定所有东西都用canvas
作者: woodheadz    时间: 8-2-2012 01:38
原帖由 coredump 于 7-2-2012 19:10 发表
canvas的文本部分就是个灾难, 能不用完全不要用,切记!
http://simonsarris.com/blog/322- ... -considered-harmful

实际上可以直接用canvas结合div和其他html元素, 不一定所有东西都用canvas

谢谢这个链接,看起来对我非常有用。
我也发现文本渲染的效率及其低下了,不管是canvas还是svg,去掉文本之后桢率都能轻松跑到40以上。这两天正在为此头疼呢
明天试试你链接里的方法
作者: woodheadz    时间: 8-2-2012 11:23
原帖由 coredump 于 7-2-2012 19:10 发表
canvas的文本部分就是个灾难, 能不用完全不要用,切记!
http://simonsarris.com/blog/322- ... -considered-harmful

实际上可以直接用canvas结合div和其他html元素, 不一定所有东西都用canvas

效果很让人吃惊啊... chrome下帧率翻了三倍,ie下帧率翻了两倍。
更让人惊喜的是ie下文本的显示质量大幅提升! 我估计是因为ie只有在直接绘制图形、文字到屏幕的时候才会使用抗锯齿,而不对图片使用抗锯齿。
现在考虑继续测试下直接使用html渲染文本的效果
作者: coredump    时间: 8-2-2012 15:23
原帖由 woodheadz 于 8-2-2012 11:23 发表

效果很让人吃惊啊... chrome下帧率翻了三倍,ie下帧率翻了两倍。
更让人惊喜的是ie下文本的显示质量大幅提升! 我估计是因为ie只有在直接绘制图形、文字到屏幕的时候才会使用抗锯齿,而不对图片使用抗锯齿。
现在 ...

要求请客, 发工资
作者: woodheadz    时间: 8-2-2012 15:34
原帖由 coredump 于 8-2-2012 16:23 发表

要求请客, 发工资

过来,请你喝啤酒
作者: findcaiyzh    时间: 8-2-2012 15:38
原帖由 coredump 于 19-1-2012 14:46 发表

如果不需要太多的UI组件框架,而只是焦点在Canvas绘图上,也可以研究下 Fabric
https://github.com/kangax/fabric.js/
后台建立在Node.js上, 目标之一就是速度。
Demo:http://kangax.github.com/fabric.js/ki ...

Fabric的demo是用到了Html5了吗?我看chrome和IE9都能支持的挺好。
我们单位可能会用到这类的库。
作者: findcaiyzh    时间: 8-2-2012 15:40
Fabric的demo  IE8也可以。。
回头研究下。
作者: findcaiyzh    时间: 8-2-2012 15:42
woodheadz和coredump你们两个都是高手啊。
作者: woodheadz    时间: 9-2-2012 11:06
原帖由 woodheadz 于 8-2-2012 12:23 发表

效果很让人吃惊啊... chrome下帧率翻了三倍,ie下帧率翻了两倍。
更让人惊喜的是ie下文本的显示质量大幅提升! 我估计是因为ie只有在直接绘制图形、文字到屏幕的时候才会使用抗锯齿,而不对图片使用抗锯齿。
现在 ...

尝试了直接使用Html,效率只比SVG稍微快一点点
决定使用纯canvas来渲染文本了!
我把那个做法改进了一点点,绘制文本后缓存图片而不是canvas,效率基本没有影响,而内存占用从320M降低到了50M
作者: woodheadz    时间: 9-2-2012 11:31
下一步的问题就是如何完成文本的排版,主要是分行. 因为要考虑支持多语言的问题,主要是要支持由右到左的语言比如阿拉伯语和希伯来语,所以很头痛啊...
我现在甚至都找不到判定一个字符串是不是由右到左的语言的方法
作者: coredump    时间: 9-2-2012 13:10
标题: 回复 #83 woodheadz 的帖子
在canvas里搞定一个完整的Text layout引擎啊, 这个搞得有点太大了, 你可想想清楚啊, 工作量不是一点半点。
作者: woodheadz    时间: 9-2-2012 20:36
原帖由 coredump 于 9-2-2012 14:10 发表
在canvas里搞定一个完整的Text layout引擎啊, 这个搞得有点太大了, 你可想想清楚啊, 工作量不是一点半点。

不用完整的,只需要完成基本的分行,分段功能就可以,图文混排啥的都不用。
应该挺简单的,只是我还没找到识别右-左语言的方法   
实在不行我就针对单个字符来判断是不是希伯来文或者阿拉伯文
作者: woodheadz    时间: 25-2-2012 14:55
我们产品第一个原型的开发已经接近完成,这个UI framework的开发也基本结束。原型系统模拟了真实运行时的一些较复杂的动画场景,在1920*1080的分辨率下基本能够稳定在55~60帧顺畅运行,让人非常满意。
什么事都要有头有尾,我上来继续对UI Framework里面之前没有提的部分做个交代 <img src="./images/smilies/default/lol.gif" border="0" smilieid="12" alt="">&nbsp;<div><br></div><div>&nbsp;1.卷屏&nbsp;</div><div><br></div><div>卷屏我做了两个版本。第一个版本在canvas外部套一个DIV,然后利用DIV来卷屏。 我在Framwork里面加了一个ViewPort的概念,表示整个canvas上当前可见的范围。在刷新重绘的时候用这个ViewPort对重绘区域进行过滤,忽略掉不在ViewPort内的对象的重绘请求,以提高效率。</div><div>之所以一上来就选择这种方式,是因为当发生卷屏的时候,我可以通过ViewPort的变化计算出canvas上新显示出来区域,然后只重绘这些区域。我认为这样应该能极大地提高卷屏的效率,因为可以利用浏览器自身的图形能力完成原有区域的重绘。&nbsp;</div><div>做完以后发现两个致命缺陷:首先div的卷屏动画在IE9下似乎不是很顺滑,有点像是因为对卷屏的位置ie会取整来计算(不确定);其次Canvas的尺寸大小有限制,Chrome中到10000*10000以上就无法显示,IE 15000*15000以上就会崩溃。 后面这个缺陷对我们而言十分致命,因为我们需要非常大的绘制空间,而且因为会有很大倍数的缩放,所以对绘制区域的要求几乎是无限的。&nbsp;</div><div>没办法,退而求其次,我使用自己进行坐标变换来完成卷屏的做法。这样程序要简单不少,而且绘制空间是虚拟的,没有尺寸限制。但每次卷屏的时候就必须把屏幕内的所有对象全部重绘。</div><div><br></div><div><br></div><div>&nbsp;2.动画</div><div>&nbsp;动画系统很简单,相对比较麻烦的easing函数算法,网上很容易就能找到MIT协议的代码。值得一提的内容就是调用端的包装。</div><div>我现在包装成这样的:
shape.moveTo(100, 100).onFinished(function(){shape.alphaTo(0).onFinished(function(){shape.parent.removeChild(shape);})});&nbsp;</div><div>这行代码执行后,shape会移动到100,100,然后逐渐变透最后后消失。&nbsp;</div><div>本来想包装成这样:</div><div>shape.moveTo(100,100).alphaTo(0).onFinished(function(){shape.parent.removeChild(shape);});&nbsp;</div><div>但发现要实现这个有点复杂,所以放弃了。&nbsp;
</div><div><br></div><div>动画系统还有一个细节,我提供了一个function beginInvoke(callback)方法,传入一个回调函数后,这个回调函数会在下一帧动画渲染执行前被执行。这个小功能在绘图逻辑十分复杂的情况下十分有用。</div><div>以我们的系统为例:我们的系统是data=&gt;viewModel=&gt;view的结构,因为呈现逻辑十分复杂,所以在data和view之间增加了一个viewModel层,负责根据data计算如何呈现。整个ViewModel层全部运行在beginInvoke回调的函数中,这样当用户修改data造成data的多处关联变动之后,只需要进行一次viewModel的计算即可。&nbsp;</div><div><br></div><div>&nbsp;3.其它&nbsp;</div><div>感觉javascript执行起来还是比较慢。做复杂的应用务必要考虑这点。我在做1000个对象的动画测试时,发现仅仅只是坐标矩阵的计算,就能让帧率从60帧降到40帧。Chrome js效率快得变态,而IE... 哎....&nbsp;</div><div><br></div><div>&nbsp;我和老板提了下把这个framework开源的问题,老板似乎很不乐意,因为转移到html5/js平台肯定是个趋势,但这个平台上目前还没有很棒的框架。如果我们公司的竞争对手得到这个framework,必然对他们会有很大的帮助。这种框架本身应用领域属于小众市场,我们也不大可能靠他获得什么利益。<img src="./images/smilies/default/sad.gif" border="0" smilieid="2" alt="">&nbsp;</div><div><br></div><div>&nbsp;最后,要感谢下老丐无私的帮助,帮我解决了最为头疼也是影响巨大的文本渲染效率问题;也要谢谢black_zerg等几位提供意见的同学 <img src="./images/smilies/default/good.gif" border="0" smilieid="45" alt=""></div>

[ 本帖最后由 woodheadz 于 25-2-2012 15:58 编辑 ]
作者: fcq731    时间: 26-2-2012 18:08
用extjs也不错
作者: black_zerg    时间: 26-2-2012 18:48
提示: 作者被禁止或删除, 无法发言 强,搞个在线demo瞧瞧啊,就是看看,不要代码。或者搞个utube录像好了,省得怕泄露
作者: woodheadz    时间: 26-2-2012 23:59
原帖由 black_zerg 于 26-2-2012 19:48 发表
强,搞个在线demo瞧瞧啊,就是看看,不要代码。或者搞个utube录像好了,省得怕泄露

回头产品发布了就能给大家看效果了
其实这个framework不是很复杂。只要避开我前面走过的一些弯路,你也能很快做出一个来




欢迎光临 FreeOZ论坛 (https://www.freeoz.org/bbs/) Powered by Discuz! X3.2