H5C3J 学习笔记 part6 AreaDivider KineticJS

由于之前利用的ivank库,受限于WebGL,我开始尝试寻找一个较为通用的,利用Canvas做绘图开发的库,然后找到了,KineticJS,我花了一个下午的时间,学习了它的教程。
结论是非常完备,非WebGL,于是决定用这个Lib继续完成之前想要完成的试题。

然后有了这样的阶段性结果:

[![](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525885.44.02.png)](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525885.44.02.png)
动态效果请猛击[这里](http://hector.ziki.me/kinetic/cubes/AreaDivider.html)。 嗯,我承认在实现分区计算的功能上,我严重地跑偏了……啊,居然去实现了一个伪3D效果,嗯,既然实现都实现了,就记录一下吧。

实现鸟瞰效果的思路是,以整个画布的中心点,作为鸟瞰的视点,假设视线为垂直向下,则所有方块产生高差时,相对中心,都需要有一个偏移,计算办法如下:

 var xDif = 50*(levelRate) * (i-5);  
 var yDif = 40*(levelRate) * (j-4);  
`</pre>
其中,i,j为当前方块坐标,levelRate,为该方块升高到某一高速时,相对视角角度放大的倍数。

一旦有了偏移,同时有了扩大,就会感觉它明显接近了视点。为了增强立体效果,我决定为其描绘侧方位的暗影四边形。

以画布中心为原点,做直角坐标系后,可以简单的划分为四个象限。
<div>[![](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525887.59.41.png)](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525887.59.41.png)</div>
以象限1为例(直角坐标系象限好像是以右上为第一象限吧……),所有发生位移的方块中可见的仅为右方和下方的,也就是,从中心视点望去,可见的面,以此类推,只要绘制原始方块,和位置变化后方框的边线,就不难展现出一种立体效果。

在这里,可以很方便的利用Tween实现Rect类的弹起移动效果,但是绘制不规则多边型时,传入的参数为一个点描述的数组,我有点摸不清头脑该怎么用它,尝试用使用Tweener(AS3Lib)的函数风格,却查找不到对应的onUpdate回调函数,最后忽然大圣上身,觉得,干脆把变化后的数组作为目标传递给它丫的,跑起来看看,结果果然完美奏效了。
<pre>` poly1= new Kinetic.Polygon({  
   points: [[rLocal[2],rLocal[3]],[rLocal[2],rLocal[3]],[rLocal[4],rLocal[5]],[rLocal[4],rLocal[5]]],  
   fill: shadowLightColor,  
   stroke: '#bbbbbb',  
   strokeWidth: 1  
 });  
 layer.add(poly1);  
 poly1.tween = new Kinetic.Tween({  
   node: poly1,  
   duration: .5,  
   points: [[rLocal[2],rLocal[3]],[rTo[2],rTo[3]],[rTo[4],rTo[5]],[rLocal[4],rLocal[5]]],  
   easing: theStandupEasing  
 }).play();  

进而,出现的是利用2DAPI构建立体效果时的常见问题,就是遮挡问题,首先要明确处于不同位置的点,在以中心为观察点时,各个点的能见度,我的计算办法是:
以中心点为基点,所有方块的中心点到基点的距离,视为可见值v,v越小,可见程度越高。

经过计算,值的分布情况如下

[![](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525888.18.46.png)](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525888.18.46.png)
通过观察可以发现,处于对称部位的值,是相等的,值相等的各个部位,以刚刚的绘制算法操作,阴影面无论如何都是不会叠加的,例如距离最近的v=32的四个近中心点,在升起时,会出现下面效果:
[![](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525888.25.48.png)](https://archive.writeitdown.site/%2525E5%2525B1%25258F%2525E5%2525B9%252595%2525E5%2525BF%2525AB%2525E7%252585%2525A7%2525202013-09-28%252520%2525E4%2525B8%25258B%2525E5%25258D%2525888.25.48.png)
因此,我的实现办法是,将这些v值相等的方块,全都放置到同样的Layer中,然后按照v值的大小排序,v值最小的在层次最上面。
至于后面的其他部分,KineticJS的[官方教学文档](http://www.html5canvastutorials.com/kineticjs/html5-canvas-events-tutorials-introduction-with-kineticjs/)非常简明易懂,不再记录(话说他是html5canvastutorials.com的官方推荐文档啊),下一步我会继续用我认为最明确的方式,实现分区计数办法的演示程序。
PS:有些可惜的一件事是,这个例子在iphone上运行,会导致 Safari & Chrome崩溃 (啊-_-#) 我会更进一步的尝试jQueryMobile或者PhoneGap,这个圈真大。