今天继续学习 kity. 根据前面了解的 svg, kity.Paper 大致应对应 svg 画布, 各种 Shape 大致对应 svg 图形元素.
因此需要查看 kity.Paper 类, 以及各个 kity.Shape 类, 了解它们如何封装, 以及有什么扩展, 便利性处理?
根据文档, 新建画布: var paper = new kity.Paper(id);
设置尺寸: paper.setWidth(width); setHeight(...)
添加图形: paper.addShape(new kity.Rect()), 批量添加: addShapes(...)
移除图形: paper.removeShape(); 图形元素移除自己: rect.remove()
根据这一接口, 大致可理解为 paper 是一个容器(可能用数组或链表实现元素的管理), 容器本身属性通过
一组 get/set 方法获取/设置. 容器中元素通过 get/add/remove 获取和增删. 让我们深入代码看看.
Paper 类定义为:
var Paper = Class.createClass('Paper' (类名), {
mixins: [共 4 个混入类],
ctor: 构造,
renderTo, createSVGNode,
get/set Node/Container/Width/Height/ViewPort/Matrix, Transform 等,
add/remove Resource 等?
});
大致是这些.
对于简单的 getWidth, setWidth 实现为对一个 node 的相应属性读写:
getWidth(): return this.node.clientWidth;
setWidth(): this.node.setAttribute('width', width); (有点不太对称...?)
对于 get/set Viewport 等, 由于涉及几何变化, 只能稍后研究了.
add/remove resource 似乎对象内部用一个 resources[] 数组维护资源, 同时有一个 resourceNode
应对应 svg 中的 defs(猜测) 节点, 以将实际 resource 添加到节点中.
createSVGNode() 函数创建一个 <svg> 节点, 添加其属性如 xmlns, version 等.
ctor(): 构造中, 创建出 <svg> 节点, 将节点<->对象双向关联起来. 向 <svg> 节点添加 <defs> 资源容器节点,
<g> 子图形容器节点. 以及别的 mixins 等的初始化.
相关的几个类有 this.resources = new Container(). 以及 4 个 mixins.
== 相关类 Container ==
var Container = Class.createClass('Container', {
get Item(根据index得到单个), Items(估计是全部), FirstItem, LastItem, indexOf(), each(fn)
add, set, append, prepend, remove, clear.
event: onContainerChanged() 容器变化事件.
});
根据接口来看是一个通用容器类, 底层是以数组 this.items[] 为容器的, 包装了一下...
其实如果不用很多功能, 则不包装也没有太大问题.
另外容器变化事件的设计有点怪, 当增删元素时调用自己的一个函数 onContainerChanged(), 看起来
像是想让子类重载这个方法? 可是还要写子类, 那就太麻烦了...
== 被 mixin 的类1: ShapeContainer ==
var ShapeContainer = createClass('ShapeContainer', {
base: Container, 果然从 Container 基类派生.
handle Add/Remove 估计从 onContainerChanged() 调用, 当 add/remove 图形元素时,
同时增删 svg 中的 DOM 元素. 也即同步功能? 或事件通知功能?
get/add/remove Shape: 被映射为 get/add/remove Item 的实现. 其它 put/append/prepend 类似(略).
});
综合起来看, 是混入了管理 shape 的一组方法, 同时负责增删变化时和实际 svg 节点的同步.
== 被 mixin 的类2: EventHandler ==
var EventHandler = createClass(..., {
ctor:
add/addOnce/remove EventListener(): 似乎增删指定事件的侦听器(由kity维护的)
on, once, off: add/addOnce/remove 的别名(简写).
fire, trigger: 触发事件.
});
这里机理大概是每个对象赋予一个 unique_id 作为事件容器标识, 事件增删在该 id 下的一个数组(或对象),
当 fire 的时候找到 event-handler function, 组建 event 对象并调用它. 大概是仿 DOM 事件?
实验: 我们在页面创建一个 paper 对象, 查看该对象数据, 看到有 _EVENT_UID=1;
另创建的 text 对象也有该属性 _EVENT_UID=2, (Circle 对象类同)
== 被 mixin 的类3: Styled ==
var Styled = createClass(..., {
add/remove/has/set Class/Style: 估计是增删改 css 样式? 看起来像 jQuery 对应的 addClass()
removeClass()...
});
== 被混入的类4: ViewBox ==
var ViewBox = createClass(..., {
getViewBox(): 得到 svg node 的 viewBox 属性.
setViewBox(): 设置 svg node 的 viewBox 属性(大概应是 'x y width height' 格式的字符串?)
});
好奇搜索了一下, Paper 类和 View 类混入了此 ViewBox 类功能.
综合以上, Paper 对应 <svg> 节点, 是 shape 容器, 是 resource 容器, 可处理自定义 event,
可设置自己的 css, 可设置 viewbox.
另有一个重要的类 Shape, 推测 Rect, Circle, Poly 等多个图形类从其派生.
var Paper = createClass(..., {
ctor, mixins:[3个混入类],
get/set Id, Node, BoundaryBox, RenderBox, Width, Height, Size, Opacity, Visible, Ancestor, ...
get/set Transform, Matrix, Translate, Rotate, Scale...
stroke, fill, get/setAttr(通用 attr?)
});
构造中创建对应 tagName 的 svg 节点, 将 shape对象<->DOM对象 相互绑定起来. 初始化 transform=empty.
get/set Id 获得/设置 svg node 的 id. 这个 id 可能是 svg.create 方法自动产生了缺省的一个. 可唯一标识.
getxxxBox 暂时略. getWidth, Height, Size: 与 box 尺寸有关.
get/set Opacity: 设置透明度(node 的 attr);
transform: 估计 matrix,translate,rotate 等都是变换, 可通过某个 3*3 矩阵表示, 暂时略.
stroke(), fill(): 对应 svg 节点的 stroke, fill 属性?
已知此类并不是只在这里有函数, 别的地方(如 Paper 类处) 有对此类的一些方法添加.
三个混入类: EventHandler, Styled 前面看过, 下面研究 Data mixin.
== 被 mixin 的类: Data ==
var Data = createClass(..., {
set/get/remove Data: 含一个 _data{} 对象, set 等方法即访问/维护它.
});
可能是为 Shape 提供额外数据容器, 别的地方可将所需数据绑定到 shape 对象.
综上所述, Shape (基类) 提供与 svg 节点的对应, 有尺寸, css 属性, 变换, 绘制, 额外数据等支持.